调试C++预处理器

17
我正在尝试构建Amaya。当构建失败并出现以下错误时:
错误:在“(”标记之前预期未限定的ID
我使用仅带有预处理器的g ++(将-c选项替换为-E)在未能编译的文件上运行,以查看发生了什么。这生成了一个80,000行的文件,向我展示“Blue”已被替换为(2 << 8),这清楚地解释了错误。如果我更正此错误,则该文件可以编译成功。我想我可以接受这一点,但我想找出为什么会发生这种情况。
有没有办法跟踪预处理程序如何替换特定字符串,例如“Blue”?
================= 更新 ===================
好吧,我找到了罪魁祸首:
> headers=`g++ [omited for brevity] -M  \
    ../../thotlib/dialogue/AmayaClassicNotebook.cpp`

> for file in $headers ; do grep -s -H Blue $file | grep "(2 << 8)";done 

/usr/local/include/gc.h:#define Blue (2 << 8) 

因此加入 #undef Blue 解决了问题。因此,使用 -M 和 grep 的组合似乎可以解决问题,但有时候 C++ 预处理器定义可能会很复杂;我想知道是否有更好的方法,例如一些聪明的 GNU 工具。

3个回答

12

我发现跑步

g++ ... -dD -E $file > $file.ii

man g++中得知,它在解决预处理问题方面非常有用。

-dD Dump all macro definitions, at the end of preprocessing,
    in addition to normal output.

似乎在预处理期间检测到语法错误时,-dD和-E都不会输出任何内容,这在某些情况下有点不方便。 - Dan Olson

3
如果没有更好的方法(基于预处理文件中的源代码信息),您可以使用-M选项获取由源文件包含的头文件列表,并在其中搜索“Blue”。我希望有可能某种混淆方式意味着这不能找到您要查找的内容,但通常您会在某个地方找到定义。

1

这个常年的问题出了什么错

find /src -exec grep Blue {} /dev/null ';'

这通常对我有用,至少作为第一步。


另一个可以使用grep命令搜索的地方是系统头文件,例如/usr/include。 - laalto
1
在这种情况下,#define 宏定义位于系统位置,而不是源代码目录下的文件中。 - Alex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接