Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When can optimizations done by the compiler destroy my C++ code?

When can optimizations done by the compiler cause my C++ code to exhibit wrong behaviour which would not be present had those optimizations not been performed? For example, not using volatile in certain circumstances can cause the program to behave incorrectly (e.g. not re-reading the value of a variable from memory and instead only reads it once and stores it in register). But are there other pitfalls which one should know about before turning on the most aggressive optimization flag and afterwards wondering why the program doesn't work anymore?

like image 343
gablin Avatar asked Sep 01 '10 17:09

gablin


2 Answers

Just don't work from the assumption that the optimizer ever destroys your code. It's just not what it was made to do. If you do observe problems then automatically consider unintentional UB.

Yes, threading can play havoc with the kind of assumptions you are used to. You get no help from either the language or the compiler, although that's changing. What you do about that is not piss around with volatile, you use a good threading library. And you use one of its synchronization primitives wherever two or more threads can both touch variables. Trying to take short-cuts or optimizing this yourself is a one-way ticket into threading hell.

like image 111
Hans Passant Avatar answered Nov 15 '22 19:11

Hans Passant


Compiler optimizations should not affect the observable behavior of your program, so in theory, you don't need to worry. In practice, if your program strays in to undefined behavior, anything could already happen, so if your program breaks when you enable optimizations, you've merely exposed existing bugs - it wasn't optimization that broke it.

One common optimization point is the return value optimisation (RVO) and named return value optimization (NRVO) which basically means objects returned by value from functions get constructed directly in the object which is receiving them, rather than making a copy. This adjusts the order and number of constructor, copy constructor and destructor calls - but usually with those functions correctly written, there's still no observable difference in the behavior.

like image 45
AshleysBrain Avatar answered Nov 15 '22 20:11

AshleysBrain