10

假设我在各种头文件中有#define foo。它可能会扩展到一些不同的事物。我想知道(在编译 .cc 文件时)遇到#define 时,它​​会扩展什么,它是哪个文件以及它是从哪里包含的。

是否可以?如果没有,是否有任何可能有帮助的部分解决方案?

随时添加带有澄清请求的评论。

编辑:当前的答案似乎集中在有一个#define 并且我只想跳到定义或知道定义是什么的情况上。这是简单的情况,是的,您的解决方案有效。但是当我在不同的文件中有相同的#define,并且想知道哪个是第一个启动时,这些技术都没有用。好的,我实际上使用#warning 仔细找到了正确的位置。但这需要做很多工作。

4

6 回答 6

18

你看 :

# 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 预处理阶段后停止;不要正确运行编译器。  
     输出以预处理源代码的形式发送到
     标准输出。

     不需要预处理的输入文件将被忽略。

注意:评论正确地抱怨这只是部分解决方案。它不会告诉您何时替换宏。它向您显示了预处理的源代码,无论如何这都会有所帮助。

于 2008-11-14T18:48:32.870 回答
5

我想知道(在编译 .cc 文件时)遇到#define 时,

我知道一个解决方案。使用已定义为非法 C++ 代码的符号编译文件(链接到的文章使用“@”)。所以,对于 GCC,你会写

gcc my_file.c -Dfoo=@

当它扩展时,它肯定会导致语法错误,编译器应该告诉你语法错误在哪个文件中,这将非常有帮助。

如果您使用 Raymond Chen 建议的技巧,编译器可能会告诉您“冲突”定义的来源,并可能会为您提供包含它的列表。但不能保证。因为我不使用宏(我更喜欢 const 和 enum),所以我不能说 GCC 是否是这方面更智能的编译器之一。我不相信 C 或 C++ 标准对此有任何说明,除非一旦预处理器运行,您就会丢失各种有用的信息。

于 2008-11-15T00:45:09.607 回答
2

它不会帮助您找到它的定义位置,但您可以使用 -E -dM 标志查看特定文件的定义

g++ -E -dM file.cpp | grep MACRO
于 2008-11-14T18:51:49.993 回答
1

对于“它将扩展什么”,我使用 gcc 中的 -E 开关,它给出了预处理的输出。但是没有回溯哪个宏来自哪里(或者是否有宏)。

您可能使用的另一个选项是-g3,这会添加有关宏的调试信息,即稍后您可以在调试器中查看每个宏的定义。

于 2008-11-14T18:51:26.607 回答
1

一个好的 IDE 可以通过某种形式的跳转到定义按需为您执行此操作。

于 2008-11-14T19:20:33.490 回答
0

使用#warning。它在这里描述。

于 2008-11-14T18:48:03.400 回答