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

Die*_*Epp 17 c gcc warnings longjmp

我有这样的功能:

#include <setjmp.h>
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);
}
Run Code Online (Sandbox Code Playgroud)

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

test.c: In function ‘func’:
test.c:5: warning: argument ‘x’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Wclobbered]

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

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

所以,

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

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

  • 或者我错过了什么?

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

#include <setjmp.h>
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);
}
Run Code Online (Sandbox Code Playgroud)

Die*_*Epp 12

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

功能属性:

returns_twice

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

因此,GCC似乎没有任何"特殊知识" setjmp,它只是暗示它确实如此.所有它知道的是setjmp返回两次,而不是它总是在第一次返回0并且之后返回非零.天哪,那本来不错.


rod*_*igo 6

来自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.
Run Code Online (Sandbox Code Playgroud)

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

  • 这是当地的功能,如函数的参数一样,当地的自动变量.
  • setjmp如果some_global为真,它的值可能会改变.
  • 它不易变.

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

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

  • 看来你没有看我的问题。我明确表示我不关心 x 是否被破坏,因为它在 `setjmp` 返回后不被使用。我想知道是否有办法在本地抑制警告。 (2认同)