Подтвердить что ты не робот

GCC 4.8: Does -Og подразумевает -g?

Недавно была обновлена ​​документация для GCC 4.8, которая теперь вводит новый переключатель оптимизации -Og. Это

[..] обращается к необходимости быстрой компиляции и превосходному опыту отладки при обеспечении разумного уровня производительности во время выполнения. Общий опыт разработки должен быть лучше уровня оптимизации по умолчанию -O0.

Этот переключатель подразумевает -g или мне нужно добавить его в мой CXXFLAGS вручную?

4b9b3361

Ответ 1

Короткий ответ: Нет, вы все равно должны добавить -g вручную.

Длинный ответ:

Я изо всех сил пытался найти жесткий ответ прямо из источника, поэтому решил сам проверить его, используя описанные здесь методы: Как проверить, была ли скомпилирована программа с помощью отладочных символов?

Я построил исполняемый файл с флагом -O3 и без -g. Использование objdump --syms <file> | grep debug ничего не дало, как ожидалось.

Затем я построил исполняемый файл с -g и без каких-либо флагов оптимизации. Та же команда objdump дала шесть результатов, таких как:

0000000000000000 l d .debug_info 0000000000000000 .debug_info

Наконец, я создал исполняемый файл с флагом -Og и без -g. Команда objdump ничего не дала. Это означает, что в этом случае присутствуют символы отладки не.

Пока я не могу найти явную документацию непосредственно из GCC, Gentoo Wiki (как упоминалось ранее Марко Сканнадинари) подтверждает мое утверждение что -Og не означает -g.

Ответ 2

Взгляд в исходный код GCC 4.9.2 (gcc/opts.c) показал, что -Og совпадает с -O1, но с некоторыми отключенными флагами, что может привести к худшему опыту отладки:

/* 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;

Несколько шагов спустя функция maybe_default_option вызывается с набором опций и флагом x_optimize_debug. Параметры, отмеченные OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_LEVELS_1_PLUS_SPEED_ONLY и OPT_LEVELS_2_PLUS_SPEED_ONLY, не будут включены, если используется -Og.

Так вот откуда происходит утверждение "должно быть лучше, чем -O0". -Og находится между -O0 и -O1. Это не влияет на включение отладочной информации, которая была бы включена с помощью опций -g. Вы, вероятно, также будете интересоваться различными опциями -g:

  • Опция -ggdb переопределяет -g. То есть, если вы установите -ggdb после -g, параметр -g будет эффективно проигнорирован.
  • Опция -g равна -g2, а опускание -g совпадает с -g0.
  • Вариант -g3 создает большую часть отладки, чем -g2, а также -ggdb3 против -ggdb2.
  • Более высокие уровни оптимизации приводят к увеличению секций кода и отладки. (-O0 < -O1 < -Og < -O2 < -O3).
  • strip --strip-debug привел к тому же размеру объекта, который не зависит от уровней -g. Это соответствовало ожиданию того, что только уровень -O влияет на фактический код, где -g определяет разделы отладки.
  • strip --keep-debug приводит к объектам, в которых в качестве размера доминирует уровень -g, за которым следуют уровни -O. (поэтому -g0 -O3 меньше -g3 -O0).

Примечание: здесь я не считаю время компилировать. Это, скорее всего, будет увеличиваться с более агрессивными уровнями оптимизации. Я ожидал бы, что уровни отладки будут лишь незначительно влиять на время (по сравнению с оптимизацией), поскольку это просто означает, что во время пропусков нужно отслеживать дополнительные детали.

Вот команда, которую я использовал для проверки фактического поведения (также сравните -ggdbX вместо -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