When you want to build something that's debuggable (g++ specifically, but perhaps shares an answer with gcc), what's the best -O level? In other words, when building a "debug" target rather than a "release" target.
The gcc online docs are a little sketchy when comparing -O0 and -O1 (here). My interpretation is that -O1 only enables one optimization that even may affect debugability, which is -fomit-frame-pointer. But to quote the doc, it's only enabled in -O1 "where doing so does not interfere with debugging." Am I interpreting that correctly?
Another post on this site (here) talks about -O2 specifically, and the answer is basically "it works but you get out-of-order execution". Which, IMO, can range from annoying to devastating depending on how badly things jump around.
GCC 4.8 introduces a new optimization level: -Og
for the best of both worlds.
-Og
Optimize debugging experience. -Og enables optimizations that do not interfere with debugging. It should be the optimization level of choice for the standard edit-compile-debug cycle, offering a reasonable level of optimization while maintaining fast compilation and a good debugging experience.
This way some optimization is done so you get better performance, better possibly-uninitialized variable detection and you can also step through a program in GDB without jumping back-and-forth through the function.
So... what flags are appropriate for the debug build?
Whatever you are comfortable debugging.
When you build with -g -O0
, debugging is easiest, but the code runs very slowly.
When you build with -g -O1
, you will start observing optimization sometimes. You'll try to step into a function, and discover that it got inlined, etc.
With -g -O2
, you'll notice optimization a lot. You'll get optimized out
when printing variables [1], you'll get unexpected jumping around in the code, etc.
With -g -O3
you'll see the same symptoms, but more frequently.
GCC doesn't actually have levels beyond -O3
, so that's the end of the line.
People who understand transformations that GCC performed with -O3
will have little trouble debugging that code (you can always peek at the assembly, figure out where the variable you want actually resides, and go from there). But for mere mortals it is usually quite hard to debug -O2
code.
[1] There is current work in GDB and GCC to reduce the number of optimized out
instances, but it's not finished yet.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With