我怎样才能让gcc警告我"int i = i;"

not*_*ble 27 c c++ gcc std compiler-warnings

一个简单的程序:

int main()
{
    long i = i;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译为C不会出现错误,也不会出现警告.

$ gcc -Wall -Wextra -pedantic 1.c
Run Code Online (Sandbox Code Playgroud)

编译为C++会发出警告:

$ c++ -Wall -Wextra -pedantic 1.c
1.c: In function ‘int main()’:
1.c:3:7: warning: ‘i’ is used uninitialized in this function [-Wuninitialized]
  long i = i;
Run Code Online (Sandbox Code Playgroud)

在两种情况下,变量i似乎都是0,尽管在c ++中它可能是未初始化的.我实际上在我的一个功能中犯了这样的错字,很难找到它.我该怎么做才能避免这种情况?我希望至少有一个警告.此外,Clang在任何一种情况下都不会给出任何警告(c或c ++).是否有标准的特定部分说明了这种行为?

编辑:尝试了类似的东西:

$ cat 1.c
int main(void)
{
    int k = k + 0;
    int i = i + 1;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

警告(在C中)仅针对"i"生成.

$ gcc -Wall -Wextra 1.c
1.c: In function ‘main’:
1.c:4:6: warning: ‘i’ is used uninitialized in this function [-Wuninitialized]
  int i = i + 1;
Run Code Online (Sandbox Code Playgroud)

ric*_*ici 18

对于GCC编译C程序,您需要添加编译器标志-Winit-self.(你还需要-Wall或者-Wuninitialized,见下文.)对于GCC编译C++程序,这个标志是隐含的,-Wall但对于C,它需要明确指定; 它不属于-Wextra任何一部分.

对于Clang来说,情况稍微有点儿了.在OP的片段中,Clang不会产生任何诊断.但是,使用下面GCC手册中提供的略有不同的片段,提供了诊断:

int f() {
  int i = i;
  return i;
}
Run Code Online (Sandbox Code Playgroud)

不同之处在于,在上面的片段中,i实际使用了(未初始化的)值.显然,在原始代码中,Clang检测到变量是无用的,并在应用诊断之前将其作为死代码消除.

在Clang中,诊断由触发-Wuninitialized,由-WallGCC 启用.


以下是GCC手册的摘录:

-Winit-self (仅限C,C++,Objective-C和Objective-C++)

警告用自己初始化的未初始化变量.请注意,此选项只能与-Wuninitialized选项一起使用.

例如,GCC警告i只有在-Winit-self指定时才会在以下代码段中未初始化:

        int f()
          {
            int i = i;
            return i;
          }
Run Code Online (Sandbox Code Playgroud)

-Wall在C++中启用此警告.

如摘录所示,-Wuninitialized也是必需的.在C和C++中,-Wall暗示着-Wuninitialized.但请注意,除非还要求某些优化级别,否则将无法检测到许多未初始化的用途.(-Winit-self据我所知,这不适用.可以在没有优化的情况下检测到.)


令人恼火的是,当您将问题标记为重复时,先前标记的重复项将消失.我没有标记它,因为没有一个重复实际上回答了正文中的问题; 我还编辑了标题.

作为参考,这里是原始的重复,可能是有意义的: