Unexpected stuff!

Let’s have a look at this code:

And let’s compile it with g++ using the flag -O3, what’s going to happen?

Before answering, let’s have a look at the assembly, shall we?

This is actually only a portion of the whole assembly, what I care to show you is the main loop and what’s going on, in the code you can skip the process of calling cout which is somwehere between L4 and the call to L6, and just have a look at the looping condition, there’s something weird there!

Note that jump to L15 is not going to happen (in this particular piece of code), and both jumps to L6 and L16 are not terminating the loop, so where is the loop end condition then?

Well, there’s no end condition, this code will print numbers forever!

If i change the code this way:

The assembler output will be:

Most of the code is the same, but now there’s a termination condition and the loop properly exit when the 500 iterations are performed, so the output will be what we’re expecting.

The point of this post is simple, do not ever ignore the warnings your compiler is issuing, many of them may cause serious problems! In many real project indeed, warnings are considered second class citizen, and nobody care about fixing them on-the-fly!

This lead to compilation outputs with hundreds of warnings which from time to time are under the scope, and people are asked to clean the mess up, you know the corporate way: “Fix the warnings as ASAP as possible! Why nobody fixed them before??” said the manager which refused to let people fix them before, no time for that 🙂

Anyway, the problem in this code is the undefined behavior in the expression i*20000000, for i values starting from 108 the multiplication cause an integer overflow, modern compilers will infer that since there’s an undefined behavior which is an unacceptable thing, then it shouldn’t happen at all and the programmer must have taken actions for this situation, therefore it must be the case that i will never be greater than 107, thus the condition i<500 is always true.

Which lead to an infinite loop..

When compiling this code, the compiler will raise the following warning:

Which should give us some hint that something is going to be very wrong, we don’t want to have undefined behavior in our code, the fix for the problem (if you don’t want to fix the code) the just compile the program with the flag -fno-aggressive-loop-optimizations.

For details about the original source of information for this problem have a look at HERE, or the related thread on SO.

Always take care of your compiler warnings!

Thanks for reading!

Leave a Reply