有任何实用程序可以测试扩展 C/C++ #define 宏吗?

问题描述 投票:0回答:5

我似乎经常花费太多时间试图让#define 宏完全按照我想要的方式进行。我将在下面发布我当前的困境,感谢任何帮助。但真正更大的问题是,是否有人可以推荐任何实用程序来快速显示宏实际上在做什么?如果我能看到问题所在,那么即使是缓慢的试错过程也会变得更快。

目前,我正在从我制作的 DLL 中动态加载一长串函数。按照我设置的方式,函数指针与导出函数具有相同的名称,并且用于原型化它们的 typedef 具有相同的名称,但前面带有下划线。所以我想使用定义来简化一长串函数指针的赋值。

例如,在下面的代码语句中,'hexdump'是typedef函数点的名称,也是函数的名称,而_hexdump是typedef的名称。如果 GetProcAddress() 失败,则失败计数器会递增。

if (!(hexdump = (_hexdump)GetProcAddress(h, "hexdump"))) --iFail;

所以假设我想用宏替换上面的每一行,就像这样......

GETADDR_FOR(hexdump )

这是我迄今为止想到的最好的。它不起作用(我的 // 注释只是为了防止消息中的文本格式)...

// #define GETADDR_FOR(a) if (!(a = (#_#a)GetProcAddress(h, "/""#a"/""))) --iFail; 

再说一遍,虽然我很想了解自己所犯的愚蠢错误,但如果有一个实用程序,只需插入我的宏即可显示我的方法的错误,这会让我很开心。

c++ macros c-preprocessor
5个回答
126
投票

前往https://godbolt.org/。在左窗格中输入代码,然后选择编译器作为 gcc,将参数设置为右窗格中的 -E。您的预处理代码将出现在右侧。


34
投票

您可以通过预处理器运行您的代码,它将显示它将被扩展成什么(或根据需要吐出错误):

$ 猫交流
#define GETADDR_FOR(a) if (!(a = (#_#a)GetProcAddress(h, "/""#a"/"")))
GETADDR_FOR(十六进制转储)

$ gcc -E a.c
#1“交流”
#1“”
#1“”
#1“交流”
a.c:1:36: 错误:“#”后面没有跟宏参数

GETADDR_FOR(十六进制转储)

在 GCC 中,

gcc -E foo.c
仅对文件进行预处理。

Visual Studio 使用

/P
参数。



5
投票

您似乎对 C 预处理器宏中字符串化或标记粘贴的确切语法感到困惑。

您可能会发现此页面有关 C 预处理器宏的一般信息 很有帮助。

特别是,我认为这个宏应该这样读:

#define GETADDR_FOR(a) if (!(a = (_##a)GetProcAddress(h, #a))) --iFail

应该跳过尾随的

;
,因为您可能会将其键入为
GETADDR_FOR(hexdump);
,如果不这样做,它在 C 代码中看起来会很奇怪,并且会混淆许多语法荧光笔。

正如其他人提到的

gcc -E
将运行预处理器并跳过其他编译步骤。这对于调试预处理器问题很有用。


3
投票

您可能想看看Boost Wave。与大多数 Boost 一样,它实际上更像是一个库,而不是一个实用程序,但它确实有一个驱动程序可以充当完整的预处理器。

© www.soinside.com 2019 - 2024. All rights reserved.