Kon*_*lph 8 c++ warnings initialization g++
我正在使用带有警告级别的g ++ -Wall -Wextra并将警告视为错误(-Werror).
现在我有时会收到错误" 变量可能在此函数中未初始化".
"有时"我的意思是我有两个独立的编译单元,它们都包含相同的头文件.一个编译单元编译没有错误,另一个编译单元给出上述错误.
头文件中的相关代码如下.由于功能很长,我只复制了下面的相关位.
确切的错误是:
'cmpres'可以在此函数中未初始化使用
我在*下面用错误标记了这一行.
for (; ;) {
int cmpres; // *
while (b <= c and (cmpres = cmp(b, pivot)) <= 0) {
if (cmpres == 0)
::std::iter_swap(a++, b);
++b;
}
while (c >= b and (cmpres = cmp(c, pivot)) >= 0) {
if (cmpres == 0)
::std::iter_swap(d--, c);
--c;
}
if (b > c) break;
::std::iter_swap(b++, c--);
}
Run Code Online (Sandbox Code Playgroud)
(cmp是一个算符,它有两个指针x和y与返回-1,0或1,如果*x < *y,*x == *y或*x > *y分别,其他变量是指针到相同的阵列.)
这段代码是一个更大的功能的一部分,但该变量cmpres被用于其他地方.因此,我无法理解为什么会产生此警告.此外,编译器显然明白这cmpres将永远不会被读取未初始化的(或至少,它并不总是警告,见上文).
现在我有两个问题:
为什么行为不一致?这个警告是由启发式生成的吗?(这是合理的,因为发出此警告需要控制流分析,这在一般情况下是NP难的,并且不能总是执行.)
为什么警告? 是我的代码不安全?我已经开始欣赏这个特别警告,因为它在其他情况下使我免于很难检测到错误 - 所以这是一个有效的警告,至少有时候.它在这里有效吗?
zwo*_*wol 13
诊断没有假阴性或阳性的未初始化变量的算法必须(作为子程序)包括解决停止问题的算法.这意味着没有这样的算法.这是不可能的计算机获得的这个时间合适的100%.
我不知道GCC的未初始化变量分析是如何工作的,但我知道它对早期优化传递对代码所做的事情非常敏感.所以我有点不会惊讶你有时会得到误报.它确实区分了可以确定无法确定的情况 -
int foo() { int a; return a; }
Run Code Online (Sandbox Code Playgroud)
生产"警告:'A’ 是用于在该功能未初始化"(重点煤矿).
编辑:我发现一个案例,最近版本的GCC(4.3及更高版本)无法诊断未初始化的变量:
int foo(int x)
{
int a;
return x ? a : 0;
}
Run Code Online (Sandbox Code Playgroud)
早期优化注意到如果x非零,则函数的行为是未定义的,因此它们假设x必须为零并用" return 0;" 替换函数的整个主体.这在生成使用未初始化警告的传递之前发生,因此没有诊断.有关血腥的详细信息,请参阅GCC错误18501.
我部分地提出这一点,以证明生产级编译器可以通过两种方式获得未初始化的变量诊断错误,部分原因是它是未定义行为可以在执行时间向后传播的一个很好的例子.关于测试没有任何未定义x,但由于依赖于代码控制x具有未定义的行为,因此允许编译器假定永远不满足控件依赖性并丢弃测试.