Gcc pure / const函数和longjmp

时间:2014-03-16 03:09:47

标签: c gcc const longjmp

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

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

2 个答案:

答案 0 :(得分:2)

The documentation for function attributes特别提及"具有无限循环的函数"作为非纯函数的例子,所以我认为,当标记为pure的函数没有'时,你可以依赖来表现良好的行为。回来。由于const被描述为更严格的版本,因此也可能同样适用它。

  

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

根据相同的文档,纯函数可以进行常见的子表达式消除和循环优化"。我不确定那些可以涵盖的内容。例如,如果"循环优化"包括编译器愿意重新排序语句,以便为循环的纯函数 out 进行因子分析 - 也就是说,如果

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

可以转换为类似

的内容
tmp = my_pure_function(17);
while (...) {
    ...;
}

- 然后显然使用longjmp注释__attribute__((pure)) - 函数可能会导致某些代码无法执行,否则本来就会执行。

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

答案 1 :(得分:1)

纯函数不能合理地缺少返回类型。鉴于中止永远不会返回,在我看来,指定一个可能不会返回为'pure'的函数正在拉伸它。因为longjmp有副作用而且纯函数不应该有任何副作用,所以你的函数听起来像是纯属性的不良候选者。

如果为函数指定const属性,则可以重新排序。如果你然后longjmp或abort,你可能会发现自己在另一个重要命令的功能之前跳跃或中止。这可能会导致未定义的行为,听起来像是一场噩梦。

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