I compiled a C program with -O0 -Wall
and then -O1
, -O2
, -O3
and I received different warning messages, some of them actually important enough that they showed actual bugs (for instance a function returning a string that was local instead of static in -O1
IIRC).
Why is that ? Can I get more warnings ?
-O1 (optimize minimally) -O2 (optimize more) -O3 (optimize even more) -Ofast (optimize very aggressively to the point of breaking standard compliance)
You can use the -Werror compiler flag to turn all or some warnings into errors. Show activity on this post. You can use -fdiagnostics-show-option to see the -W option that applies to a particular warning. Unfortunately, in this case there isn't any specific option that covers that warning.
GCC has a range of optimization levels, plus individual options to enable or disable particular optimizations. The overall compiler optimization level is controlled by the command line option -On, where n is the required optimization level, as follows: -O0 . (default).
Turning on optimization flags makes the compiler attempt to improve the performance and/or code size at the expense of compilation time and possibly the ability to debug the program. The compiler performs optimization based on the knowledge it has of the program.
Some optimization levels of gcc analyze the code a bit more deeply than others, which can also lead to the detection of errors. One example is loop optimization, that is performed from optimization level 2 on.
Consider this code:
void func (void) {
char buf[9];
for (i = 0; i < 10; i++)
buf[i] = i;
}
If you compile it with O0 or O1, no loop optimization is performed. But on level O2 and upwards, the compiler detects, that the last loop iteration invokes undefined behaviour:
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++)
^~~
So yes, heavy optimizations can help detecting bugs because gcc puts more effort into analyzing the code for optimization purposes.
Edit:
For this specific warning, actually the Value Range Propagation optimization (-ftree-vrp) is responsible.
From the gcc documentation:
This is similar to the constant propagation pass, but instead of values, ranges of values are propagated. This allows the optimizers to remove unnecessary range checks like array bound checks and null pointer checks. This is enabled by default at -O2 and higher. Null pointer check elimination is only done if -fdelete-null-pointer-checks is enabled.
Edit 2:
The observations may differ with the gcc version; in this case, gcc version 8.3.0 was used.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With