A look in the GCC 4.9.2 source code (gcc/opts.c) showed that -Og
is the the same as -O1
, but with some flags disabled that could result in a worse debugging experience:
/* in function default_options_optimization: */
case OPT_Og:
/* -Og selects optimization level 1. */
opts->x_optimize_size = 0;
opts->x_optimize = 1;
opts->x_optimize_fast = 0;
opts->x_optimize_debug = 1;
break;
A few steps later, function maybe_default_option
gets called with a set of options and the x_optimize_debug
flag. Options marked with OPT_LEVELS_1_PLUS_NOT_DEBUG
, OPT_LEVELS_1_PLUS_SPEED_ONLY
and OPT_LEVELS_2_PLUS_SPEED_ONLY
will not be enabled when -Og
is used.
So this is where the statement “should be better than -O0” comes from. -Og
is between -O0
and -O1
. This does not affect the inclusion of debugging information that would be enabled through the -g
options. You would probably also be interested in the different -g
options:
- Option
-ggdb
overrides-g
. That is, if you set-ggdb
after-g
, the-g
option effectively gets ignored. - Option
-g
is equal to-g2
and omitting-g
is the same as-g0
. - Option
-g3
produces a larger debugging section than-g2
and so does-ggdb3
against-ggdb2
. - Higher optimization levels both result in an increase of the code and debugging sections. (
-O0
<-O1
<-Og
<-O2
<-O3
). strip --strip-debug
resulted in the same object size independent of the-g
levels. This matched the expectation that only the-O
level has an effect on the actual code where-g
determines the debug sections.strip --keep-debug
results in objects where the size is dominated by the-g
level, followed by-O
levels. (so-g0 -O3
is smaller than-g3 -O0
).
Note: here I did not consider the time to compile. It will likely increase with more aggressive optimization levels. I would expect that the debug levels would only have a minor impact on the time (compared to optimization) since it just means that extra details needs to be tracked during passes.
Here is the command I used to test the actual behavior (also compare -ggdbX
instead of -gX
):
for g in -g0 -g2 -g3;do
for O in -O0 -O1 -O2 -O3 -Og; do
flags="$g $O";
gcc -fPIC -rdynamic -c -Wall -Wextra -Ilib ltunify.c -o obj/gL_"${flags// /_}_.o" $flags || break;
done;
done