为什么在这个简单的例子中我没有收到来自 gcc 的 "used uninitialized" 警告?

why am I not getting an "used uninitialized" warning from gcc in this trivial example?

How to fix this segmentation error in a sequence inverting program?.

中又出现了一个愚蠢的未初始化变量错误

所以我打算重复 "please use -Wall flags" 评论,但是当我针对警告测试代码时,令我非常惊讶的是没有报告任何警告。

所以我将其缩减为以下内容(这段代码对于执行目的没有意义,但它说明了我想要展示的内容):

#include <stdio.h>

int main()
{

  int i,len=12;

  /* printf("%d\n",i); */

  while(i!=len-1)
  {

    i++;
    len--;
  }

 return 0;
 }

使用 gcc 4.7.3 和 6.2.1 编译时使用

gcc -Wall -Wextra -pedantic

我没有收到警告,而 iwhile 循环中使用之前公然未初始化。

现在,如果我取消对 printf 语句的注释,我会得到:

warning: 'i' is used uninitialized in this function [-Wuninitialized]

那么为什么在通过 iprintf 而在 while 测试中没有发出警告?

(这与 gcc failing to warn of uninitialized variable 不同,因为在我的情况下,没有分支)

(听起来像是个错误,但它太微不足道了,我想知道我是不是漏掉了什么大东西。)

很难说它是一个 bug,因为 gcc 混淆了用于优化和创建警告的代码,甚至针对此特定警告进行了记录:

-Wuninitialized
Warn if an automatic variable is used without first being initialized or if a variable may be clobbered by a setjmp call. [...]
Because these warnings depend on optimization, the exact variables or elements for which there are warnings depends on the precise optimization options and version of GCC used.

(来自 GCC 文档 Options to Request or Suppress Warnings,强调我的)

您在这里发现了一个恕我直言的非常愚蠢的案例。试试 -O1,你会得到一个意想不到的警告:

warn.c: In function ‘main’:
warn.c:13:6: warning: ‘i’ may be used uninitialized in this function [-Wmaybe-uninitialized]
     i++;
      ^

所以,gcc还是漏掉了第一个未初始化的使用,但是找到了第二个!尝试 -O0-O2,警告再次消失...

您仍然可以尝试提交有关此的错误。注意 clang 做对了:

warn.c:10:9: warning: variable 'i' is uninitialized when used here
      [-Wuninitialized]
  while(i!=len-1)
        ^
warn.c:6:8: note: initialize the variable 'i' to silence this warning
  int i,len=12;
       ^
        = 0
1 warning generated.