C++ 我如何才能让gcc警告我;int i=i&引用;

C++ 我如何才能让gcc警告我;int i=i&引用;,c++,c,gcc,std,compiler-warnings,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 [-Wun

一个简单的程序:

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++中它可以是未初始化的。我实际上在我的一个函数中输入了这样一个错误,很难找到它。我能做些什么来避免这种情况?我希望至少有一个警告。此外,在这两种情况下(c或c++),Clang都不会给出任何警告。标准中是否有特定部分说明了这种行为

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

$ cat 1.c
int main(void)
{
    int k = k + 0;
    int i = i + 1;
    return 0;
}
警告(在C中)仅针对“i”生成

基本上是:

int i;
i = i;

其中,
i
是未初始化的值。

对于GCC编译C程序,需要添加编译器标志
-Winit self
。(您还需要<代码> -Walth或 -WunRealsial,参见下面)。对于GCC编译C++程序,该标志由<> >墙>代码暗示,但对于C,需要明确指定;它也不是
-Wextra
的一部分

对于Clang来说,情况稍微有趣一些。在OP中的代码段中,Clang不会产生任何诊断。但是,使用下面GCC手册中提供的稍有不同的代码段,提供了一个诊断:

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

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


以下是GCC手册的摘录:

<强> <代码> - Winit自我< />代码(C,C++,ObjuleC和Objul-C++)< <强> > /P> 警告使用自身初始化的未初始化变量。注意:此选项只能与

-Wuninitialized
选项一起使用

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

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

此警告由C++ > -Currue/Cult>在C++中启用。

正如摘录所示,
-Wuninitialized
也是必需的。在C和C++中, -Walth隐含了<>代码> -WunIn初始化。但是,请注意,除非还请求某些优化级别,否则将无法检测到许多未初始化的使用。(据我所知,这不适用于
-Winit self
。可以在不进行优化的情况下检测到。)


令人恼火的是,当您将问题取消标记为重复问题时,以前标记的重复问题将消失。我取消了标记,因为没有一个副本真正回答了正文中的问题;我还编辑了标题

以下是可能感兴趣的原件副本,以供参考:


    • 结合
      -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;
                ^
      

      C通常可以处理垃圾值,但这有点令人惊讶,特别是在使用Python这么长时间之后(我期待一个NameError:)。警告是一个“实现质量”问题。该标准对它们一无所知。@KABoissonneault它在C中仍然是未定义的行为。由于C中未初始化的变量具有垃圾数据,因此执行此类操作的结果是不可预测的,甚至当所述变量用于语句的RHS时,它也会编译,因为C&C++的规则不够严格或不够好。非古代语言不允许这种构造。“不可预测的数据”是一种未指明的行为形式。未定义的行为意味着对实现的功能没有任何限制do@notnonuninvisibleC和C++不是,也从来都不是“安全语言”。扭曲编译器以防止任何可能的人为错误是没有意义的。这就是UB在这些语言中成为一种东西的全部原因。这是如何回答这个问题的?在“变量i可能未初始化使用”这一行中有一条警告,编译器可能会显示这一点warning@notnonuninvisible-我没说“坏”。我说“不安全”。这是不一样的。缺乏安全也是一种力量,因为没有任何东西会让你受到不需要的安全网的困扰。我很抱歉,但是讨论这个哲学观点是离题的。唯一允许的离题点是在重复中回答的,我相信我选择了这个。这个讨论离主题太远了。这个答案似乎没有回答“我如何才能让gcc警告我关于‘int I=I;’”的问题。具体来说,它是由
      -Wuninitialized-Winit self
      启用的(前者是由
      -Wall
      启用的)在使用编译器选项之前,您必须发现自己的警告有什么意义?gcc的男孩有时做一些有点棘手的事情!!!:)
      $ 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;
                ^