Intereting Posts
C Определение препроцессора для тестирования нескольких макросов Чтение значений из файла CSV в переменные Как установить заданную точку входа в цель эльфа, используя сценарий ld Почему GCC не бросает предупреждение в этом примере C: как перенаправить stderr из System-command в stdout или файл? Почему распределение памяти в куче MUCH медленнее, чем на стеке? файлы целевого файла makefile Создание типа MPI_Datatype для структуры, содержащей указатели Что означает «CRT обнаружено, что приложение записано в память после окончания буфера кучи» означает? Как два процесса могут разговаривать друг с другом без pipe ()? d2i_RSA_PUBKEY, d2i_RSAPrivateKey и d2i_RSAPublicKey возвращает NULL Распределение памяти для массива указателей структуры Как выводить одновременно на консоль и текстовый файл так, чтобы они были идентичны int отличается в уровне косвенности от char error Массивы переменной длины в структуре

Gcc определяет что-либо, когда указано -g?

Вскоре я хочу знать, что gcc (или g ++. Мне это нужно в C , но также интересно, о c ++) определяет любые специальные символы, если -g включен. Является ли? Если да, то какие символы?

В процессе поиска я узнал, что:

  • _DEBUG определяется вручную (вручную я имею в виду -D_DEBUG ) и является привычкой, используемой программистами Visual C (поскольку VC определяет _DEBUG при компиляции в режиме отладки)
  • NDEBUG определяется, если NOT в режиме отладки. Хотя я нашел несколько мест, говорящих об этом, я пробовал с моими файлами gcc и g ++ в файлах .c и .cpp и ни в одном из них с или без -g такой символ не был определен!

Edit : Позвольте мне показать, почему я не хочу использовать нестандартный символ:

Представьте себе модуль ядра, который что-то делает, а также предоставляет заголовочные файлы для включения в другие модули ядра, чтобы они могли подключаться к этому.

Теперь как средство, в одном из файлов заголовков у меня есть:

 #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 сам, но тогда, если кто-то включает мой заголовок, они могут не определять этот символ. Конечно, я могу сказать им «кстати, чтобы получить заголовки в режиме отладки, определить этот другой символ», но это просто не подходит для меня.

Я мог бы определить символ в заголовке и включить его во все файлы заголовков. Таким образом, если они include один из моих заголовков, они также получают символ отладки. Проблема в том, что если они не хотят компилироваться в режиме отладки, мои заголовки все еще думают, что они находятся в режиме отладки.

Так что лучше всего было бы использовать символ, который определяется при использовании -g , если они есть!

Обновить

До сих пор я пришел к выводу, что могу сделать что-то вроде этого:

how_to_build.h

 #if !defined(NDEBUG) #define MY_DEBUG #endif 

Использование:

 #include "how_to_build.h" #ifdef MY_DEBUG // rest of the story 

Таким образом, общий вариант NDEBUG удаляет мое определение. Мне по-прежнему требуется, чтобы я сказал им, чтобы они определяли его, если они не хотят получать заголовки в режиме отладки.

Вы можете увидеть список всех макросов gcc / g ++ для любой комбинации таких флагов:

 $ g++ -E -dD -xc++ /dev/null 

Например:

 [max@truth ~]$ g++ -E -dD -xc++ /dev/null > a [max@truth ~]$ g++ -E -dD -xc++ -g -O3 /dev/null > b [max@truth ~]$ diff ab 1a2 > # 1 "/home/max//" 173c174 < #define __NO_INLINE__ 1 --- > #define __OPTIMIZE__ 1 

Давайте посмотрим, определяет ли -g что угодно:

 [max@truth ~]$ g++ -E -dD -xc++ -g /dev/null > c [max@truth ~]$ diff ac 1a2 > # 1 "/home/max//" 

Дополнительная препроцессорная директива, но не дополнительно определяет флаг -g .

Бег
g++ -E -dD -xc++ /dev/null
против
g++ -E -dD -g -xc++ /dev/null
не показывает лишних определенных символов.

Это, в сочетании с отсутствием какой-либо документации, в которой указано, что символы определены, должно быть достаточно, чтобы спокойно сказать, что ничего не определено.

Как говорили другие, и, как видно из руководства , GCC не предоставляет никаких внутренних макросов, которые указывают, будет ли генерироваться отладочная информация ( -g mode). Я хочу добавить, что это специально.

Давным-давно оригинальные авторы GCC (RMS, Kenner, вероятно, еще пара) решили, что включение информации отладки не должно вызывать каких-либо изменений для фактического кода, чтобы уменьшить риск ошибки, загадочно исчезающей при попытке отладки это . Это основной принцип дизайна в GCC, и даже сегодня разработчики стараются сохранить его.

Определение макроса будет нарушать этот принцип проектирования, поскольку это позволит исходному коду изменять себя в ответ на -g .