任何测试扩展C/C++ #define宏的实用程序?

Ran*_*dy 34 c++ macros c-preprocessor

看起来我经常花太多时间试图让#define宏完全按照我的意愿去做.我将在下面发布我目前的困境,任何帮助表示赞赏.但真正更大的问题是,是否有人可以推荐的任何实用程序,以快速显示宏实际上在做什么?如果我看到错误的话,即使是缓慢的试错过程似乎会更快.

目前,我正在从我制作的DLL动态加载一长串函数.我设置的方式,函数指针与导出的函数具有相同的nanes,并且用于原型化的typedef具有相同的名称,但具有前置下划线.所以我想使用一个define来简化长长的函数指针列表的赋值.

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

if (!(hexdump = (_hexdump)GetProcAddress(h, "hexdump"))) --iFail;
Run Code Online (Sandbox Code Playgroud)

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

GETADDR_FOR(hexdump )
Run Code Online (Sandbox Code Playgroud)

那么这是迄今为止我提出的最好的.它不起作用(我的//注释只是为了防止消息中的文本格式化)...

// #define GETADDR_FOR(a) if (!(a = (#_#a)GetProcAddress(h, "/""#a"/""))) --iFail; 
Run Code Online (Sandbox Code Playgroud)

而且,虽然我很了解我已经犯下了什么愚蠢的错误,但是通过简单地插入我的宏,这将使我的日子能够显示出我的方式错误.

Moh*_*hit 36

在此输入图像描述转到https://godbolt.org/.在左窗格中输入您的代码,然后选择编译器作为gcc,将参数设置为右窗格中的-E.您的预处理代码将显示在右侧.

  • 很棒的工具!应该是最重要的答案,因为它需要最少的工作量. (3认同)

Mar*_*off 23

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

$ cat a.c
#define GETADDR_FOR(a) if (!(a = (#_#a)GetProcAddress(h, "/""#a"/""))) 
GETADDR_FOR(hexdump)

$ gcc -E a.c
# 1 "a.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "a.c"
a.c:1:36: error: '#' is not followed by a macro parameter

GETADDR_FOR(hexdump)

在GCC中,它gcc -E foo.c只是预处理文件.

Visual Studio中使用/P参数.

  • @Randy:实际上,Jerry Coffin推荐的Boost Wave有一个"替换跟踪"功能,它输出一个文件,显示在宏替换过程中所采取的步骤.它非常冗长,因为通常会有比我们通常想象的更多的步骤,但它可能非常有用,特别是对于复杂或长宏定义. (2认同)

小智 6

http://visualstudiogallery.msdn.microsoft.com/59a2438f-ba4a-4945-a407-a1a295598088 - 用于扩展宏的visual studio插件

  • @AndrewBarber 他在评论中提到他访问了 MSDN (2认同)
  • 链接无效 (2认同)

Omn*_*ous 5

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

您可能会发现此有关C 预处理器宏的页面总体上很有帮助。

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

#define GETADDR_FOR(a) if (!(a = (_##a)GetProcAddress(h, #a))) --iFail
Run Code Online (Sandbox Code Playgroud)

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

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