如何知道(在 GCC 中)何时声明了给定的宏/预处理器符号?
Posted
技术标签:
【中文标题】如何知道(在 GCC 中)何时声明了给定的宏/预处理器符号?【英文标题】:How to know (in GCC) when given macro/preprocessor symbol gets declared? 【发布时间】:2008-11-14 18:28:19 【问题描述】:假设我在各种头文件中有#define foo。它可能会扩展到一些不同的事物。我想知道(在编译 .cc 文件时)遇到#define 时,它会扩展什么,它是哪个文件以及它是从哪里包含的。
有可能吗?如果没有,是否有任何可能有帮助的部分解决方案?
如有澄清请求,请随时添加 cmets。
编辑:当前的答案似乎集中在有一个#define 并且我只想跳到定义或知道定义是什么的情况上。这是简单的情况,是的,您的解决方案有效。但是当我在不同的文件中有相同的#define,并且想知道哪个是第一个启动时,这些技术都没有用。好的,我实际上使用#warning 仔细找到了正确的位置。但这需要做很多工作。
【问题讨论】:
当它在编译时运行到您的宏中时,您究竟希望它做什么? @Greg:打印信息:刚刚定义了这样的。将扩展到(...)。这是在文件 (...) 的行 (...) 中。包含自(“#includes 回溯到我的 .cc 文件)。 我对任何有影响的软件都有一种非常糟糕的感觉。 【参考方案1】:使用 -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 预处理阶段后停止;不要正确运行编译器。 输出以预处理源代码的形式发送到 标准输出。 不需要预处理的输入文件将被忽略。
注意:cmets 正确地抱怨这只是部分解决方案。它不会告诉您何时替换宏。它会向您显示经过预处理的源代码,这无论如何都会有所帮助。
【讨论】:
这适用于整个文件,而不是单个#defines,它不提供@phjr 正在寻找的其余信息。 确实,这只是部分解决方案:) 如果不使用'-P'(保留内部),可以很容易地看到定义了文件宏。【参考方案2】:我想知道(在编译 .cc 文件时)遇到#define 时,
I know a solution to that。使用已定义为非法 C++ 代码的符号编译文件(链接到的文章使用“@”)。所以,对于 GCC,你会写
gcc my_file.c -Dfoo=@
当它扩展时肯定会导致语法错误,编译器应该告诉你语法错误在哪个文件中,这将非常有帮助。
如果你使用 Raymond Chen 建议的技巧,编译器可能告诉你“冲突”定义的来源,可能给你一个它是如何得到的列表包括。但不能保证。因为我不使用宏(我更喜欢 const 和 enum),所以我不能说 GCC 是否是这方面更智能的编译器之一。我不相信 C 或 C++ 标准对此有任何说明,除非一旦预处理器运行,您就会丢失各种有用的信息。
【讨论】:
好主意,但如果定义由#ifndef foo
保护,这将不起作用。【参考方案3】:
它不会帮助您找到它的定义位置,但您可以使用 -E -dM 标志查看特定文件的定义
g++ -E -dM file.cpp | grep MACRO
【讨论】:
然后从底部寻找你的宏。要知道该文件,您可以找到相应的 _HEADER_FILE_H 定义。【参考方案4】:对于“它将扩展什么”,我使用 gcc 中的 -E 开关,它给出了预处理的输出。但是没有回溯哪个宏来自哪里(或者是否有宏)。
您可能使用的另一个选项是 -g3,这会添加有关宏的调试信息,即您稍后可以在调试器中查看每个宏的定义。
【讨论】:
【参考方案5】:一个好的 IDE 可以通过某种形式的跳转到定义按需为您执行此操作。
【讨论】:
【参考方案6】:使用#warning。它被描述为here。
【讨论】:
以上是关于如何知道(在 GCC 中)何时声明了给定的宏/预处理器符号?的主要内容,如果未能解决你的问题,请参考以下文章