Benjamin Bannier
Benjamin Bannier

Reputation: 58764

Why would one ever want to compile with -O2 instead of -O3

We usually compile with -O2 because -O3 would "trigger subtle bugs".

For our GCC version -O3 enables more aggressive inlining which would actually reveal bugs otherwise unnoticed (e.g. use of uninitialized values from functions taking them as reference arguments or out-of-bounds access for arrays). It seems to me this aggressive inlining also allows a more expressive way of coding with smaller functions and -funswitch-loops helps keeping variable definitions more local in loops.

Given that bugs in our code are orders of magnitude more likely than compiler bugs and that we use -Wall -Wextra without any issues what kind of bugs should we be looking for?

If it matters we use gcc-4.3.2. Compile time is not a major issue for us.

Upvotes: 21

Views: 6427

Answers (3)

Sled
Sled

Reputation: 18979

Sometimes aggressive optimisation can break code just like you mentioned. If this is a project you are currently working on, then perhaps this is not a problem. However, if the code in question is legacy code that is fragile, poorly written, and not well-understood, then you want to take as few chances as possible.

Also, not all optimisations are formally proven. That means that they may alter the behaviour of programs in undesirable ways.

The best example I can think of is a Java one, but it should illustrate my point about optimisations in general.

It is common to have code like this

 while( keepGoing ){
      doStuff();
 }

Then value of keepGoing gets modified by another thread. Well one optimisation that the JVM will do, is see that keepGoing is not modified within the body of the loop, so it "elevates" it and checks before the loop, essentially transforming the code into:

 if( keepGoing ){
      while( true ){
           doStuff();
      }
 }

Which in a multi-threaded environment is not the same thing, but in a single-threaded it is. These are the kinds of things that can break with optimisations. This is a frequent source of "Heisenbugs".

PS- In Java the proper answer is the make keepGoing "volatile" so it cannot presume cached values and would do what you intend.

Upvotes: 3

timday
timday

Reputation: 24892

Don't kid yourself that compiler bugs aren't lurking out there to make your life hell. Here's a nasty one which cropped up in Debian last year, and where the fix was to fall back to -O2.

Upvotes: 5

flolo
flolo

Reputation: 15526

Size. Of course if size does really matters (sometimes is does, like embedded), one would use -Os. But main difference at O3 is the (from you already mentioned) inlining. This can increase the generated code size (but it is faster). Maybe you want speed, but not at all (space) cost? Otherwise I would see no reason why not to use O3 (except you know of a gcc compiler bug that only occurs in your code at O3, but as long as you dont have an error, you cant reproduce at O2, I would not care).

Upvotes: 14

Related Questions