我编译了一个 C 程序,-O0 -Wall然后使用-O1, -O2,-O3我收到了不同的警告消息,其中一些实际上非常重要,以至于它们显示了实际的错误(例如,返回一个本地字符串而不是-O1IIRC 中的静态字符串的函数)。
这是为什么 ?我能得到更多警告吗?
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版。