Cpp:如何理解和/或调试复杂的宏?
我正在尝试学习预处理器技巧,我发现这不是那么容易(,,…) 我知道-E选项可以查看预处理器整个过程的结果,但我想知道,是否存在逐步查看结果的选项或方法。事实上,有时很难理解当一个宏调用一个调用宏的宏时会发生什么。。。在禁用上下文的机制下,绘制蓝色。。。简而言之,我想知道是否存在一种带有断点和其他工具的预处理器调试器。Cpp:如何理解和/或调试复杂的宏?,c,macros,c-preprocessor,variadic-macros,stringification,C,Macros,C Preprocessor,Variadic Macros,Stringification,我正在尝试学习预处理器技巧,我发现这不是那么容易(,,…) 我知道-E选项可以查看预处理器整个过程的结果,但我想知道,是否存在逐步查看结果的选项或方法。事实上,有时很难理解当一个宏调用一个调用宏的宏时会发生什么。。。在禁用上下文的机制下,绘制蓝色。。。简而言之,我想知道是否存在一种带有断点和其他工具的预处理器调试器。 (不要回答使用预处理器指令是危险的、丑陋的、可怕的,在C语言中不是很好的做法,会产生不可读的代码……我知道这一点,这不是问题所在)。是的,此工具作为的一个功能存在。我认为访问该功能
(不要回答使用预处理器指令是危险的、丑陋的、可怕的,在C语言中不是很好的做法,会产生不可读的代码……我知道这一点,这不是问题所在)。是的,此工具作为的一个功能存在。我认为访问该功能的默认方式是将鼠标悬停在希望看到展开的宏上(这将显示完全展开),然后按键盘上的
F2
(出现一个弹出窗口,允许您逐步展开)
当我使用这个工具来了解更多有关宏的信息时,它非常有用。只要稍加练习,你就不再需要它了
如果有人对如何使用此功能感到困惑,我会在Eclipse文档中找到一个教程。查看宏错误的唯一方法是添加一个选项,该选项将在编译完成时保留临时文件。对于gcc,它是
-save temps
选项。您可以打开.i
文件和展开的宏
IDE索引器(如Eclipse)不会有太大帮助。在错误发生之前,它们不会展开宏(与其他应答状态一样)。
这与另一个问题相关
当你使用奇怪的预处理器技巧(这是合法的)时,要求编译器生成预处理表单(例如使用gcc-C-e
,如果使用)并查看预处理表单是很有用的
实际上,对于源文件foo.c
,使用gcc-c-efoo.c>foo.i
获取其预处理形式foo.i
并查看该foo.i
是有意义的
有时,在没有行信息的情况下获取foo.i
也是有意义的。这里的技巧(删除以#
开头的行中包含的行信息)是:
gcc -C -E foo.c | grep -v '^#' > foo.i
然后您可以缩进foo.i
并编译它,例如使用gcc-Wall-cfoo.i
;您将在预处理文件中获得错误位置,您可以理解如何获得错误位置,并返回到预处理器宏(或它们的调用)
请记住,转换主要是在文件级别进行的文本转换。不可能单独宏扩展几行(因为先前的行可能与#一起使用#如果
与#定义
-可能在先前的中-或者像-DNDEBUG
传递给gcc
或g++
)。关于Linux,请参见
一个已知的扩展示例是,当使用或不使用传递给编译器的-DNDEBUG
进行编译时,其工作方式不同。assert(i++>0)
(对编码来说是一件非常错误的事情)的意义取决于它,并说明宏扩展不能在本地完成(您可能会想象以前的某个头具有#define NDEBUG 1
,当然,即使它的品味很差)
宏扩展依赖于上下文的另一个示例(实际上非常常见)是使用\uuuuu LINE\uuuu
或
注意。对于所有这些,您不需要Eclipse,只要足够好(我的偏好是,但这是一个品味问题):对于预处理任务,您可以使用您的编译器。如果您还没有,请查看您是否对高级宏感兴趣。有关更多信息,请查看P99和BoostPP@okovko。谢谢你提供的信息。这就是我试图理解的。参见Paul FulTZ II的答案(你可以在我给你的链接中找到答案。这是Paul Fultz II在他的github页面上的宏教程:P Oops,这是我打算给你的链接。它是解释:它是否存在这样的代码块选项?否则,我将安装Eclipse。我不知道其他IDE,但几年前我在寻找这个功能时,Eclipse是我唯一找到它的地方。它只有在宏正确的情况下才能工作。否则你只能看到错误(不是很友好和解释性的)。你不能“调试”宏。这根本不是真的。它显示了所有可能的扩展,直到出现错误为止。因此,该工具非常友好且具有解释性。如果您删除了您的否决票,我将不胜感激,因为您的批评是错误的。@okovko。太好了。我安装了Eclipse,它可以在您描述的一个简单示例上工作。(#define ABC BCD#define BCD 1 main(){int a=ABC;}
)。非常感谢,我验证了你的答案。但是我没有eclipse IDE中F2的所有步骤。这是我在使用-E选项时看到的,不是吗?如果宏不稳定,你没有任何步骤。eclipse viewer只支持(因为它使用内部索引器)若要查看正确的宏,请尝试回答该问题以改进答案。@okovko您不应发布错误答案。请在eclipse的宏视图(F2)中显示任何部分展开的不稳定宏。如果有错误,请使用-save temps,会发生什么情况?是否可以在输出(.i文件)中看到,第一步展开直到出错?看起来问题是特别要求逐步展开宏,而且问题还提到了-E选项。是否有任何命令行工具可以逐步展开宏?很高兴找到一个。当然,这是可能的,我只是认为还没有人做到。例如例如,它是在EclipseIDE中实现的(请参阅我的答案)。Eclipse允许您一步一步地查看每个扩展,而不仅仅是最终结果,就像您使用-E标志得到的那样