What are the possible side effects of GCC optimization?

As a newbie, I am trying to figure out what can happen when using the GCC optimization flags. Which optimization flags can cause side effects. In what specific situation should I avoid using optimization. I think optimization might break some multi-threaded code, but what else?

+3


source to share


1 answer


Compiler optimizations generally tend to preserve implementation-defined behavior (with a few exceptions, especially for aggressive floating point optimizations that are not enabled through a generic flag -O

). In other words, if the functional behavior of your program changes as a result of optimization, the program is likely to cause unspecified behavior or undefined .

You should always avoid writing programs that cause undefined behavior, and make sure that undefined behavior cannot affect the program's results. The problem is not optimization, but when calling undefined behavior or giving undefined behavior a chance to influence the results. This will cause problems if you change your compiler or compiler version, even if you keep compiling without optimization.



To answer your question as a phrase:

  • Optimization can make an uninitialized variable display as true and false , or the product of an uninitialized variable by two results in an odd value . Just don't use uninitialized variables as this is mostly undefined behavior.

  • with optimization, signed arithmetic overflow can result in an expression of a type int

    that appears to have a value greater than INT_MAX

    . A function int f(int x) { return x+1 > x; }

    compiled with optimization returns 1

    when applied to INT_MAX

    . To avoid this strange behavior, just don't rely on signed arithmetic overflow, this behavior is undefined.

  • with optimization, dangling pointers can be different and identical at the same time: just don't use dangling pointers for anything.

  • with optimization, constant expressions that cause undefined behavior can be evaluated at compile time with different semantics than the runtime semantics of a build command generated without optimization. Expect this to happen for shifts wider than the type size: with a 32-bit int

    expression, the expression 1 >> 32

    can be evaluated with 0

    and 1

    without optimization . The same can happen for floating point to integer overflow conversions : they are undefined as well.

+8


source







All Articles