2

假设我有一个 C 函数,它满足使用 GCC__attribute__((pure))或注释的标准__attribute__((const))除了对于某些输入参数,该函数可能会执行 alongjmp或 anabort或类似的事情,而不是返回。所以它不是你通常所说的“纯”函数。尽管如此,如果 GCC 仅使用这些注释来决定何时可以缓存和重用函数的返回结果,那么似乎仍然可以将这些注释应用于这样的函数。如果它确实返回,则可以假定该函数是其参数的无副作用的纯结果(可能加上全局状态,取决于我们是否使用pure或注释const)。

是否有人对这些注释是否可以在这种情况下应用有经验或知识?(我对可以依赖的工作感兴趣,而不仅仅是在某些设置或某些编译标志中发生的工作。)

4

2 回答 2

2

函数属性的文档特别提到“具有无限循环的函数”作为非纯函数的示例,所以我认为可以公平地说,当标记的函数不返回时,你不能依赖良好的行为。pure并且由于const被描述为它的更严格版本,因此大概也是如此。

[...] 如果 GCC 仅使用这些注释来决定何时可以缓存和重用函数的返回结果 [...]

根据相同的文档,纯函数可以进行“公共子表达式消除和循环优化”。我不确定这些到底能涵盖什么。例如,如果“循环优化”包括编译器愿意重新排序语句以便将纯函数排除在循环之外——也就是说,如果类似

while (...) {
    ...;
    tmp = my_pure_function(17);
    ...;
}

可以转换为类似的东西

tmp = my_pure_function(17);
while (...) {
    ...;
}

——那么显然,用longjmp-ing 函数注释__attribute__((pure))可能会导致某些代码无法执行,否则会执行。

(而且——我真的不确定——但我认为__attribute__((const))kind 的存在表明编译器愿意pure执行这些类型的重新排序优化。因为和之间的明显区别constconst函数可以更自由地重新排序,而pure函数可以' 不会在全局变量的(潜在)修改中重新排序。但这只是我的推论,我可能完全不在。)

于 2014-03-16T03:36:11.407 回答
1

纯函数不能合理地缺少返回类型。鉴于 abort 永远不会返回,在我看来,指定一个可能不会返回为“纯”的函数有点拉伸它。因为 longjmp 有副作用,而纯函数不应该有任何副作用,所以您的函数听起来不太适合纯属性。

如果您为函数指定 const 属性,它可能会被重新排序。如果您随后 longjmp 或 abort,您可能会发现自己在另一个重要的顺序函数之前跳转或中止。这可能会导致未定义的行为,并且听起来像是一场噩梦。

在给定情况下使用这些属性可能具有未定义的行为。如果您正在寻找适用于所有情况的东西,那么我会在该功能上避免使用这些属性。

于 2014-03-16T03:39:40.393 回答