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

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

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

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

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

Что именно вы хотите, чтобы он делал, когда сталкивался с вашими макросами при компиляции?

Greg Rogers 14.11.2008 21:33

@Greg: информация для печати: только что определено такое-то и такое-то. Расширяется до (...). Это файл (...), строка (...). Включено из ("след # включает возвращение к моему файлу .cc)".

Paweł Hajdan 14.11.2008 21:42

У меня было очень плохое предчувствие по поводу любого программного обеспечения, где это имело бы значение.

David Thornley 15.11.2008 01:17
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
10
3
6 250
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

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

Ответ принят как подходящий

Ты видишь :

# 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.

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

Это работает со всеми файлами, а не с отдельными #defines, и не предоставляет остальную информацию, которую искал @phjr.

Robert Gamble 14.11.2008 21:57

Действительно, это лишь частичное решение :)

Johannes Schaub - litb 14.11.2008 22:07

Если '-P' не используется (оставить внутреннее), можно легко увидеть, какой макрос файла определен.

Erdem 03.08.2012 14:10

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

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

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

g++ -E -dM file.cpp | grep MACRO

А затем найдите свой макрос снизу. и чтобы узнать файл, вы можете найти соответствующее определение _HEADER_FILE_H.

Vijayender 12.12.2012 16:42

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

I would like to know (when compiling a .cc file) when a #define is encountered,

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

gcc my_file.c -Dfoo=@

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

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

Хорошая идея, но это не сработает, если определение охраняется #ifndef foo.

skyking 15.02.2016 12:59

Другие вопросы по теме