一个简单的程序:
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;
答案 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;
^