What's the best g++ optimization level when building a debug target?
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 -开发者_如何学GoO1 "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.
debugging mode (the -g
) and optimization levels (the -O*
family) are independent issues. the -g
flag basically instructs gcc to include debugging symbols when compiling (and some hints corresponding to line numbers in the code). It can be applied to any optimization level.
The simple answer, therefore, is "the best g++ optimization level when building the production program", which is a much longer discussion
精彩评论