C 这些乱七八糟的变量警告有什么意义?

C 这些乱七八糟的变量警告有什么意义?,c,gcc,warnings,setjmp,C,Gcc,Warnings,Setjmp,我有这样一个函数: #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); } 从man longjmp: 调用后,自动变量的值未指定 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);
}

man longjmp

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

碰巧,第一个示例中的
x
变量满足以下条件:

  • 它是函数的局部变量,因为函数参数就像局部自动变量一样
  • 如果
    some_global
    为真,则其值可能会在
    setjmp
    之后更改
  • 它不易挥发
因此,其值可能未指定(被删除)


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

在略过网络,重新阅读GCC文档后,我发现:

功能属性:

返回\u两次

返回\u两次
属性告诉编译器一个函数可能返回一次以上。编译器将确保在调用此类函数之前所有寄存器都已失效,并将发出关于在函数第二次返回后可能被关闭的变量的警告。此类函数的示例有
setjmp
vfork
。此类函数的类似
longjmp
的对应项(如果有)可能需要使用
noreturn
属性进行标记


因此,GCC似乎没有任何关于
setjmp
的“专门知识”,它只是暗示它有。它只知道
setjmp
返回两次,而不是第一次总是返回0,之后总是非零。天哪,那太好了。

我认为编译器不够聪明。在启用所有警告并将其视为错误的情况下进行编译时,我不得不使用MSVC++解决一些类似的问题。很好,编译器有时可以说些什么,因为这可能会为其他知识水平较低和比我们幸运的人节省一些时间。我的gcc(4.5.2)只有在使用
-Wextra
时才会抱怨(引入
-Wclobbered
)。你在使用哪一面旗帜?@Hasturkun:看来你自己已经回答了你的问题。gcc 4.6.1没有给我任何警告。可能是版本特定的问题。@DietrichEpp:我这样问是因为
-Wuninitialized
被记录为生成类似的警告,尽管我无法让gcc以其他方式生成该消息,但您似乎没有阅读我的问题。我明确地说,我不关心x是否被删除,因为它在
setjmp
返回后不被使用。我想知道是否有办法在本地抑制警告。 test.c: In function ‘func’: test.c:5: warning: argument ‘x’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Wclobbered]
#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);
}
   ·  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.