为什么gcc不会在代码里面的未定义行为中发出警告?

时间:2011-11-26 10:19:42

标签: c++ c gcc compiler-warnings sequence-points

我刚刚阅读了this关于未定义行为和序列点的SO C ++ FAQ,并进行了一些实验。在下面的代码中,gcc-4.5.2仅在代码注释中提到的行中给出了警告,尽管之前的一行也显示了未定义的行为,不是吗?你不能说首先执行哪个加法操作数(因为+不是序列点)。为什么gcc也没有在这一行给我一个警告?

int i=0;
int j=0;

int foo(void) {
    i=1;
    return i;
}

int main(void) {
    i = i + foo(); 
    j = j + (j=1); //Here is a rightly warning
    return 0;
}

感谢您的帮助。

3 个答案:

答案 0 :(得分:16)

i = i + foo()的行为;未指定但未定义。未定义意味着允许任何可能的行为,甚至中止程序。未指定意味着首先评估i,或者foo()。是的,foo写到同一个i,但由于它发生在一个单独的语句中,所以在该商店之前和之后都有一个序列点。

答案 1 :(得分:1)

程序中的行i = i + foo();未指定但未定义。

编译器尝试发出没有误报的警告(每次编译器发出警告时,程序员都应该修复缺陷),或者至少具有非常低的误报率。这意味着作为交换,他们有相当多的漏报。为了遵循相同的理念,编译器通常不会对未指明的行为发出警告。

要获得有关您的程序的警告,您应该研究静态分析器,这些分析器对警告更具攻击性,但代价是误报率稍高。静态分析仪可以很好地决定警告未指明的行为。他们中的一些人甚至警告定义的行为虽然被定义,但表明程序员可能很困惑。

答案 2 :(得分:-6)

人类可以看到调用foo()会改变我,但对于计算机程序来说,很难看到。它只是不是为了看到这个而设计的。