Как узнать (в GCC), когда данный символ макроса / препроцессора объявлен? - PullRequest
10 голосов
/ 14 ноября 2008

Предположим, у меня есть #define foo в различных заголовочных файлах. Это может распространиться на некоторые разные вещи. Я хотел бы знать (при компиляции файла .cc), когда встречается #define, к чему он будет расширяться, к какому файлу он относится и откуда он был включен.

Возможно ли это? Если нет, то могут ли помочь какие-то частичные решения?

Не стесняйтесь добавлять комментарии с просьбами о разъяснениях.

Редактировать: кажется, что текущие ответы сконцентрированы на том случае, когда есть один #define, и я просто хочу перейти к определению или узнать, что это за определение. Это простой случай, и да, ваши решения работают. Но когда у меня один и тот же #define в разных файлах, и я хочу знать, какой из них запускается первым, ни один из этих методов не будет полезен. Хорошо, я действительно осторожно использовал #warning, чтобы найти правильное место. Но это требует много работы.

Ответы [ 6 ]

18 голосов
/ 14 ноября 2008

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

# shows preprocessed source with cpp internals removed
g++ -E -P file.cc
# shows preprocessed source kept with macros and include directives 
g++ -E -dD -dI -P file.cc  

Внутренние элементы выше - это линейные маркеры для gcc, которые немного запутывают, когда вы читаете вывод. -P полоски их

 -E  Stop after the preprocessing stage; do not run the compiler proper.  
     The output is in the form of preprocessed source code, which is sent to the 
     standard output.

     Input files which don't require preprocessing are ignored.

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

5 голосов
/ 15 ноября 2008

Я хотел бы знать (при компиляции файла .cc), когда встречается #define,

Я знаю решение для этого . Скомпилируйте файл с символом, уже определенным как недопустимый код C ++ (статья, на которую ссылается, использует '@'). Итак, для GCC вы должны написать

gcc my_file.c -Dfoo=@

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

Если вы используете трюк, предложенный Реймондом Ченом, компилятор может сообщить вам, откуда появилось "конфликтующее" определение, а может дать вам список того, как оно было включено. Но нет гарантии. Поскольку я не использую макросы (я предпочитаю const и enum), я не могу сказать, является ли GCC одним из самых умных компиляторов в этом отношении. Я не верю, что стандарты C или C ++ говорят об этом, за исключением того, что после запуска препроцессора вы теряете всякую полезную информацию.

2 голосов
/ 14 ноября 2008

Это не поможет вам найти, где оно было определено, но вы можете увидеть определение для определенного файла, используя флаги -E -dM

g++ -E -dM file.cpp | grep MACRO
1 голос
/ 14 ноября 2008

Хорошая IDE может сделать это для вас по требованию через некоторую форму перехода к определению.

1 голос
/ 14 ноября 2008

для "того, что будет расширяться", я использую ключ -E в gcc, который выдает предварительно обработанный вывод. Но нет никакого обратного следа, какой макрос пришел откуда (или был ли макрос вообще).

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

0 голосов
/ 14 ноября 2008

Использовать # предупреждение. Здесь описано .

...