What's the best g++ optimization level when building a debug target?
Asked Answered
L

3

44

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.

Louiselouisette answered 21/9, 2011 at 2:32 Comment(1)
The developers of g++ have answered this very question by carefully choosing default optimizations. The level that works best for most people is the one that is selected when you omit the -O flag.Operand
S
62

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.

Salleysalli answered 23/4, 2013 at 21:1 Comment(2)
-Og is between -O0 and -O1. See also my answer here that discusses the various -O and -g levels.Canica
In tests for one of our libraries in g++ 4.9, -Og made builds 20-25% slower than -O0. It's a great addition to GCC, but based on the compile time penalty, I don't think it should automatically be the level of choice.Irrefutable
H
34

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.

Hypochromia answered 22/9, 2011 at 2:57 Comment(3)
I'd say that the gcc have a level beyond -O3, it is -Ofast.Orthopsychiatry
There are also varying levels in -g. -g is equivalent to -g2 and -g3 can add macro expansions for example.Canica
But for mere mortals it is usually quite hard to debug -O2 code. Sounds about right.Claytonclaytonia
B
-3

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

Berhley answered 21/9, 2011 at 2:41 Comment(1)
True, DST and codegen are technically orthogonal functions and any arbitrary level of one can be applied to the other. This doesn't mean combining -g with -O5 will give you anything human readable. This is why any decent project will have debug & release targets (or modes, or flavors). So... what flags are appropriate for the debug build?Louiselouisette

© 2022 - 2024 — McMap. All rights reserved.