gcc 根据优化级别显示不同的警告

dar*_*aud 5 c debugging gcc

我编译了一个 C 程序,-O0 -Wall然后使用-O1, -O2-O3我收到了不同的警告消息,其中一些实际上非常重要,以至于它们显示了实际的错误(例如,返回一个本地字符串而不是-O1IIRC 中的静态字符串的函数)。

这是为什么 ?我能得到更多警告吗?

Ctx*_*Ctx 8

gcc 的某些优化级别比其他优化级别更深入地分析代码,这也可能导致错误检测。一个例子是循环优化,从优化级别 2 开始执行。

考虑这个代码:

void func (void) {
    char buf[9];

    for (i = 0; i < 10; i++)
        buf[i] = i;
}
Run Code Online (Sandbox Code Playgroud)

如果用 O0 或 O1 编译它,则不会执行循环优化。但是在级别 O2 及更高级别,编译器检测到最后一个循环迭代调用了未定义的行为:

main.c:5:10: warning: iteration 9 invokes undefined behavior [-Waggressive-loop-optimizations]
   buf[i] = i;
   ~~~~~~~^~~
main.c:4:2: note: within this loop
  for (int i = 0; i < 10; i++)
  ^~~
Run Code Online (Sandbox Code Playgroud)

因此,是的,大量优化可以帮助检测错误,因为 gcc 会投入更多精力来分析代码以进行优化。

编辑:

对于这个特定的警告,实际上值范围传播优化 (-ftree-vrp) 负责。

从 gcc 文档:

这类似于常量传播传递,但传播的不是值,而是值的范围。这允许优化器删除不必要的范围检查,如数组绑定检查和空指针检查。默认情况下在 -O2 及更高级别启用此功能。空指针检查消除仅在启用 -fdelete-null-pointer-checks 时完成。

编辑2:

观察结果可能因 gcc 版本而异;在这种情况下,使用了 gcc 8.3.0版。