Gcc определяет что-либо, когда указано -g?
Вкратце, я хочу знать, что gcc (или g++. Мне это нужно в C, но также интересно, о С++) определяет любые специальные символы, если -g
включен. Имеет ли это? Если да, то какие символы?
В процессе поиска я узнал, что:
-
_DEBUG
определяется вручную (по-моему, это означает -D_DEBUG
) и является привычкой, принимаемой программистами Visual C (поскольку VC определяет _DEBUG
при компиляции в режиме отладки)
-
NDEBUG
определяется, если NOT в режиме отладки. Хотя я нашел несколько мест, говорящих об этом, я попытался с помощью gcc и g++ в файлах .c и .cpp и ни в одном из них с или без -g
не был указан такой символ!
Изменить. Позвольте мне показать, почему я не хочу использовать нестандартный символ:
Представьте себе модуль ядра, который что-то делает, а также предоставляет заголовочные файлы для включения в другие модули ядра, чтобы они могли подключаться к этому.
Теперь как средство, в одном из файлов заголовков у меня есть:
#ifdef DEBUG <-- This is what I need
#define LOG(x, ...) printk("Some extra info"x, ##__VA_ARGS__);
#else
#define LOG(x, ...) printk("Without extra info"x, ##__VA_ARGS__);
#endif
Обратите внимание, что имя не действительно LOG
, что пример.
Теперь я могу использовать любой символ для DEBUG
сам, но тогда, если кто-то включает мой заголовок, они не могут определить этот символ. Конечно, я могу сказать им "кстати, чтобы получить заголовки в режиме отладки, определить этот другой символ", но это мне просто не подходит.
Я мог бы определить символ в заголовке и включить его во все файлы заголовков. Таким образом, если они включают один из моих заголовков, они также получают символ отладки. Проблема в том, что если они не хотят компилироваться в режиме отладки, мои заголовки все еще думают, что они находятся в режиме отладки.
Так что лучше всего было бы использовать символ, который определяется при использовании -g
, если они есть!
Update
До сих пор я пришел к выводу, что могу сделать что-то вроде этого:
how_to_build.h
#if !defined(NDEBUG)
#define MY_DEBUG
#endif
Использование:
#include "how_to_build.h"
#ifdef MY_DEBUG
// rest of the story
Таким образом, общий параметр NDEBUG
также удаляет мое определение. Мне по-прежнему требуется, чтобы я сказал им, чтобы определить это, если они не хотят, чтобы заголовки находились в режиме отладки.
Ответы
Ответ 1
Вы можете увидеть список всех макросов gcc/g++ для любой комбинации таких флагов:
$ g++ -E -dD -xc++ /dev/null
Например:
[[email protected] ~]$ g++ -E -dD -xc++ /dev/null > a
[[email protected] ~]$ g++ -E -dD -xc++ -g -O3 /dev/null > b
[[email protected] ~]$ diff a b
1a2
> # 1 "/home/max//"
173c174
< #define __NO_INLINE__ 1
---
> #define __OPTIMIZE__ 1
Посмотрим, определяет ли -g
что-либо:
[[email protected] ~]$ g++ -E -dD -xc++ -g /dev/null > c
[[email protected] ~]$ diff a c
1a2
> # 1 "/home/max//"
Дополнительная препроцессорная директива, но для параметра -g
нет дополнительных значений.
Ответ 2
Запуск
g++ -E -dD -xc++ /dev/null
против
g++ -E -dD -g -xc++ /dev/null
не показывает лишних определенных символов.
Это, в сочетании с отсутствием какой-либо документации с указанием того, что символы будут определены, должно быть достаточно, чтобы спокойно сказать, что ничего не определено.
Ответ 3
Как говорили другие, и как видно из руководство, GCC не предоставляет никаких внутренних макросов, которые указывают, будет ли генерироваться отладочная информация (режим -g
). Я хочу добавить, что это специально.
Давным-давно оригинальные авторы GCC (RMS, Kenner, возможно, еще пара) решили, что включение отладочной информации не должно вызывать никаких изменений в действительном коде, чтобы уменьшить риск ошибки загадочно исчезает при попытке отладить его. Это основной принцип дизайна в GCC, и даже сегодня разработчики стараются сохранить его.
Определение макроса нарушит этот принцип проектирования, так как это позволит исходному коду изменять себя в ответ на -g
.