Reputation: 33
As a newbie, I'm trying to figure out what can occur when using GCC optimization flags. Which optimization flags likely to make side effects. Which particular situation should I avoid using optimization. I guess optimization can broke some multithreading code but what else?
Upvotes: 3
Views: 908
Reputation: 80325
A compiler's optimizations generally strive to preserve implementation-defined behavior (with some exceptions, especially for aggressive floating-point optimizations that aren't enabled through the general -O
flag). In other words, if the functional behavior of your program changes as a result of optimizations, the program is probably invoking unspecified behavior or undefined behavior.
You should always avoid writing programs that invoke undefined behavior, and make sure that unspecified behavior cannot affect the results of the program. The problem is not with the optimizations, it is with invoking undefined behavior or with giving unspecified behavior a chance to influence the results. These will cause trouble when if you change your compiler, or compiler version, even if you keep compiling without optimizations.
To answer your question as phrased:
optimization can make an uninitialized variable appear as both true and false, or the product of an uninitialized variable by two result into an odd value. Simply do not use uninitialized variables, as this is basically undefined behavior.
with optimization, a signed arithmetic overflow may result in an expression of type int
apparently having a value larger than INT_MAX
. The function int f(int x) { return x+1 > x; }
, compiled with optimizations, returns 1
when applied to INT_MAX
. To avoid this strange behavior, simply do not rely on signed arithmetic overflow, it is undefined behavior.
with optimization, dangling pointers can be different and identical at the same time: simply do not use dangling pointers for anything.
with optimization, constant expressions invoking undefined behavior may be computed at compile-time with semantics different from the run-time semantics of the assembly instruction generated without optimizations. Expect this to happen for shifts wider than the size of the type: with 32-bit int
, the expression 1 >> 32
can evaluate to 0
with optimization and to 1
without. The same can happen for overflows in the conversion from floating-point to integer: they are also undefined behavior.
Upvotes: 7