我试过的所有C编译器都无法检测到下面代码片段中未初始化的变量。然而,这里的情况是显而易见的。
不要担心这个代码片段的功能。这不是真实的的代码,为了调查这个问题,我把它剥离了。
BOOL NearEqual (int tauxprecis, int max, int value)
{
int tauxtrouve; // Not initialized at this point
int totaldiff; // Not initialized at this point
for (int i = 0; i < max; i++)
{
if (2 < totaldiff) // At this point totaldiff is not initialized
{
totaldiff = 2;
tauxtrouve = value; // Commenting this line out will produce warning
}
}
return tauxtrouve == tauxprecis ; // At this point tauxtrouve is potentially
// not initialized.
}
另一方面,如果我注解掉tauxtrouve = value ;
,我会得到"local variable 'tauxtrouve' used without having been initialized"
警告。
我试了这些编译器:
- GCC 4.9.2带-Wall -WExtra
- 启用所有警告的Microsoft Visual C++ 2013
4条答案
按热度按时间2izufjch1#
这个变量没有初始化的明显性被夸大了。路径分析需要花费时间,而您的编译器供应商要么不想实现该功能,要么认为它会花费您太多的时间--或者您只是没有明确地选择加入。
例如,使用
clang
:这些简单示例的执行时间差异可以忽略不计。但是想象一下,一个翻译单元有数千行代码,数十个函数,每个函数都有循环和大量嵌套。路径的数量迅速地复合并且变成分析通过循环的第一次迭代是否将在该比较之前发生分配的大负担。
编辑:@Matthieu指出,使用LLVM/clang,由于IR使用的SSA符号,查找use-of-uninitialized值所需的路径分析不会随着嵌套的增加而复合。
它并不像我希望的那样简单,“
-S -emit-llvm
”,但我发现了他描述的SSA表示法输出。老实说,我对LLVM IR还不够熟悉,但我相信Matthieu的话。底线是:使用
clang
和--analyze
,或者说服某人修复gcc
错误。wr98u20j2#
是的,它应该对未初始化的变量发出警告,但它是a GCC bug。这里给出的例子是:
并被诊断为
-O2 -W -Wall
。不幸的是,今年是这个bug的10周年!
smtd7mpg3#
此答案仅针对GCC。
经过进一步的调查和评论,有更多的事情比我以前的回答。此代码段有两个未初始化的变量,由于不同的原因,它们中的每一个都未被检测到。
首先,
-Wuninitialized
选项的GCC文档说:由于这些警告取决于优化,因此存在警告的确切变量或元素取决于所使用的GCC的精确优化选项和版本。
以前版本的GCC手册对此有更明确的表述。以下是GCC 3.3.6手册的摘录:
只有在优化编译时才可能出现这些警告,因为它们需要仅在优化时计算的数据流信息。如果不指定-O,就不会收到这些警告。
参见GCC - no warning about an uninitialized array with -O0。
似乎当前版本在没有
-O
的未初始化变量的情况下可能会给予一些警告,但使用它仍然可以获得更好的结果。如果我使用
gcc -std=c99 -Wall -O
编译你的例子,我会得到:(Note这是GCC 4.8.2,因为我没有安装4.9.x,但原理应该是一样的。
因此,它检测到
tauxtrouve
未初始化的事实。但是,如果我们通过为
tauxtrouve
添加初始化器(但不为totaldiff
添加初始化器)来部分修复代码,那么gcc -std=c99 -Wall -O
会接受它而不会发出任何警告。这似乎是haccks's answer中引用的“bug”的一个示例。这是否真的应该被认为是一个bug还存在一些问题:GCC并不承诺捕获未初始化变量的每个可能示例。事实上,它不能以完美的精度这样做,因为这是halting problem。所以像这样的警告在正常工作时是有帮助的,但是没有警告并不能证明你的代码中没有未初始化的变量!它们真的不能代替仔细检查您自己的代码。
在bug report linked by haccks中,有很多关于bug是否可以修复的讨论,或者试图检测这个特定的构造是否会导致其他正确代码的不可接受的误报率。
70gysomp4#
Michael,我不知道你在哪个版本的Visual Studio 2013上尝试过这个,但它肯定已经过时了。Visual Studio 2013 Update 4在首次使用
totaldiff
时正确生成以下错误消息:你应该考虑更新你的工作环境。
顺便说一下,这是我在编辑器中直接看到的: