这些破坏性变量警告有何意义?

我有这样的function:

#include  jmp_buf buf; void func2(int g); extern int some_global; void func(int x) { if (setjmp(buf)) return; if (some_global) x += 5; func2(x); } 

GCC(gcc(Debian 4.4.5-8)4.4.5)发出警告:

 test.c:在函数'func'中:
 test.c:5:警告:参数'x'可能被'longjmp'或'vfork'破坏[-Wclobbered]

为什么???? 我的意思是,显然我不在乎x是否被破坏,因为它在setjmp返回后不可能被使用。 即使编译器应该知道一些非常明显的东西,因为它具有某种特殊的setjmp知识。

我的主要兴趣是找到我inheritance的代码库中的错误,因此,“使用这种编码风格代替”并不是我正在寻找的建议。 然而,这里有许多奇怪的曲折。 例如,如果x是局部变量而不是参数,那么GCC不会抱怨。 此外, if (some_global)没有if (some_global)行,GCC不会抱怨。 尼斯。 有些事情搞砸了GCC的流量分析,或者GCC知道我不知道的事情。

所以,

  • 是否有一种简单的方法来抑制此函数的此警告,就像将未使用的参数转换为(void)

  • 或者我只是在项目范围内禁止警告?

  • 或者我错过了什么?

更新:让我与您分享一个不会产生警告的略有不同的版本:

 #include  jmp_buf buf; void func2(int g); extern int some_global; void func(int y) { int x = y; if (setjmp(buf)) return; if (some_global) x += 5; func2(x); } 

在刮网之后,重新阅读GCC文档,我遇到了这个:

function属性:

returns_twice

returns_twice属性告诉编译器函数可能返回多次。 在调用这样的函数之前,编译器将确保所有寄存器都已死,并且会在第二次从函数返回后发出可能被破坏的变量的警告。 这些函数的例子是setjmpvfork 。 这种函数的longjmp like对应物(如果有的话)可能需要用noreturn属性标记。

所以看起来GCC没有任何关于setjmp “特殊知识”,它只是暗示它确实如此。 它只知道setjmp返回两次,而不是它总是第一次返回0而之后返回非零。 天哪,那本来不错的。

来自man longjmp

如果满足以下所有条件,则在调用longjmp()之后未指定自动变量的值:

  · they are local to the function that made the corresponding setjmp(3) call; · their values are changed between the calls to setjmp(3) and longjmp(); and · they are not declared as volatile. 

碰巧,第一个示例中的x变量符合条件:

  • 它是函数的本地函数,因为函数参数就像本地自动变量一样。
  • 如果some_global为true,则可以在setjmp之后更改其值。
  • 它并不易变。

所以它的价值可能是未指定的(破坏)。

关于为什么第二个版本没有发出警告……不知道。