Предположим, у меня есть #define foo в различных файлах заголовков. Он может распространяться на разные вещи. Я хотел бы знать (при компиляции файла .cc), когда встречается #define, до чего он будет расширяться, какой это файл и откуда он был включен.
Является ли это возможным? Если нет, есть ли какие-то частичные решения, которые могут помочь?
Не стесняйтесь добавлять комментарии с просьбами о разъяснениях.
Обновлено: текущие ответы, похоже, сосредоточены на случае, когда есть одно #define, и я просто хочу перейти к определению или узнать, что это за определение. Это простой случай, и да, ваши решения работают. Но когда у меня есть один и тот же #define в разных файлах и я хочу знать, какой из них срабатывает первым, ни один из этих методов не помогает. Хорошо, я на самом деле осторожно использовал #warning, чтобы найти нужное место. Но это требует большой работы.
@Greg: информация для печати: только что определено такое-то и такое-то. Расширяется до (...). Это файл (...), строка (...). Включено из ("след # включает возвращение к моему файлу .cc)".
У меня было очень плохое предчувствие по поводу любого программного обеспечения, где это имело бы значение.





Используйте # предупреждение. Это описано здесь.
Ты видишь :
# 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.
Действительно, это лишь частичное решение :)
Если '-P' не используется (оставить внутреннее), можно легко увидеть, какой макрос файла определен.
для «до чего он будет расширяться» я использую ключ -E в gcc, который дает предварительно обработанный вывод. Но нет обратной трассировки, откуда появился макрос (или был ли макрос вообще).
Другой вариант, который вы можете использовать, - это -g3, он добавляет отладочную информацию о макросах, т.е. вы можете позже увидеть в своем отладчике определение каждого макроса.
Это не поможет вам найти, где он был определен, но вы можете увидеть определение для конкретного файла, используя флаги -E -dM
g++ -E -dM file.cpp | grep MACRO
А затем найдите свой макрос снизу. и чтобы узнать файл, вы можете найти соответствующее определение _HEADER_FILE_H.
Хорошая 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.
Что именно вы хотите, чтобы он делал, когда сталкивался с вашими макросами при компиляции?