Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gcc shows different warnings depending on optimisation level

Tags:

c

gcc

debugging

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 ?

like image 678
dargaud Avatar asked Dec 18 '19 09:12

dargaud


People also ask

What are the optimization levels in GCC?

-O1 (optimize minimally) -O2 (optimize more) -O3 (optimize even more) -Ofast (optimize very aggressively to the point of breaking standard compliance)

How does GCC treat warning errors?

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.

What is default GCC optimization level?

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).

What is optimization flag in GCC?

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.


1 Answers

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.

like image 137
Ctx Avatar answered Oct 03 '22 17:10

Ctx