Fundamentals 8 min read

Unexpected Behavior with -O2 Optimization Due to Strict Aliasing Violations in C++

The article explains why a C++ program produces different outputs with and without the -O2 optimization flag, tracing the issue to strict aliasing violations caused by type‑punning pointer casts, and shows how disabling -fstrict-aliasing or using -fno‑strict‑aliasing resolves the problem.

Tencent Database Technology
Tencent Database Technology
Tencent Database Technology
Unexpected Behavior with -O2 Optimization Due to Strict Aliasing Violations in C++

The author observed that a simple C++ program behaves differently when compiled with no optimization versus with the -O2 flag. Without optimization the output is: ctor _tm = 1,hour = 0,min = 0,sec = -1 dtor With -O2 the output becomes: ctor _tm = 1,hour = 0,min = 0,sec = 1 dtor

The program stores a short integer into a bit‑field struct, zeroes the struct via a type‑punned cast, and, if the value is negative, multiplies the whole struct (treated as an int ) by -1 . The set function contains two critical lines that manipulate the struct through int* casts.

Using gdb , the author saw that after set the struct contained {second = 1, minute = 0, hour = 0, unused = 0} , indicating the negative‑value handling was omitted. Disassembly of the -O2 build shows those two lines are completely optimized away, while the unoptimized build retains them.

The root cause is the compiler’s -fstrict-aliasing optimization, which assumes that objects of different types do not alias each other. The program violates this rule by casting the address of the Foo::tm struct to int* and writing through it. Under -O2 , GCC assumes the struct has never been assigned a non‑zero value, so the expression *(int*)&_tm * -1 is treated as 0 * -1 and eliminated.

GCC normally warns about such strict‑aliasing violations (e.g., -Wstrict-aliasing ), but the original compilation suppressed the warning with -Wno-strict-aliasing , leaving the optimization active. The correct fix is to disable the strict‑aliasing assumption using -fno-strict-aliasing or to avoid type‑punning altogether.

After recompiling with -fno-strict-aliasing (or removing the offending casts), the program produces the expected output under -O2 , confirming that the discrepancy was caused by the strict‑aliasing optimization rather than a compiler bug.

C++Compiler OptimizationgccOptimization Flagsstrict aliasing
Tencent Database Technology
Written by

Tencent Database Technology

Tencent's Database R&D team supports internal services such as WeChat Pay, WeChat Red Packets, Tencent Advertising, and Tencent Music, and provides external support on Tencent Cloud for TencentDB products like CynosDB, CDB, and TDSQL. This public account aims to promote and share professional database knowledge, growing together with database enthusiasts.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.