我如何获得gcc来警告我“ int i = i;”;

时间:2018-09-25 13:02:51

标签: c++ c gcc std compiler-warnings

一个简单的程序:

int main()
{
    long i = i;

    return 0;
}

编译为C不会给出错误和警告。

$ gcc -Wall -Wextra -pedantic 1.c

以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;

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

编辑:尝试过类似的操作:

$ cat 1.c
int main(void)
{
    int k = k + 0;
    int i = i + 1;
    return 0;
}

警告(在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;

3 个答案:

答案 0 :(得分:18)

对于GCC编译C程序,您需要添加编译器标志-Winit-self。 (您还需要-Wall-Wuninitialized,请参见下文。)对于GCC编译C ++程序,-Wall暗含此标志,但对于C它需要显式指定;它也不是-Wextra的一部分。

对于Clang来说,情况稍微有些有趣。在OP的代码段中,Clang不产生任何诊断信息。但是,与下面的GCC手册中提供的代码段稍有不同,可以提供诊断信息:

int f() {
  int i = i;
  return i;
}

区别在于,在上述片段中,实际上使用了i的(未初始化)值。显然,Clang在原始代码中检测到该变量无用,并在应用诊断程序之前将其消除为死代码。

在Clang中,诊断由-Wuninitialized触发,如-Wall在GCC中启用。


这是GCC手册的摘录:

  

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

     

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

     

例如,只有在指定了i的情况下,GCC才会警告您在以下代码段中未初始化-Winit-self

        int f()
          {
            int i = i;
            return i;
          }
     

此警告由C ++中的-Wall启用。

如摘录所示,还需要-Wuninitialized。在C和C ++中,-Wall表示-Wuninitialized。但是,请注意,除非还要求某些优化级别,否则将不会检测到许多未初始化的用途。 (据我所知,这不适用于-Winit-self。无需优化即可检测到。)


令人讨厌的是,当您将一个问题取消标记为重复项时,先前标记的重复项会消失。我没有对它进行标记,因为没有一个重复项实际上回答了正文中的问题。我还编辑了标题。

作为参考,以下是原始副本,可能会感兴趣:

答案 1 :(得分:4)

基本上是:

int i;
i = i;

其中i是未初始化的值。

答案 2 :(得分:4)

-Wall -Winit-self的组合似乎可以添加此诊断信息:

$ gcc -Wall      -Winit-self t.c
t.c: In function ‘main’:
t.c:3:10: warning: ‘i’ is used uninitialized in this function [-Wuninitialized]
     long i = i;
          ^