似乎我经常花太多时间试图让#define宏完全按照我的意愿行事。我将在下面发布我目前的困境,任何帮助表示赞赏。但真正更大的问题是,是否有人可以推荐的任何实用程序,以快速显示宏实际上在做什么?如果我能看出错误的话,即使是缓慢的试错过程也会更快。
目前,我正在从我制作的DLL动态加载一长串函数。我设置的方式,函数指针与导出的函数具有相同的nanes,并且用于原型化的typedef具有相同的名称,但具有前置下划线。所以我想使用一个define来简化长长的函数指针列表的赋值。
例如,在下面的代码语句中,'hexdump'是typedef'd函数点的名称,也是函数的名称,而_hexdump是typedef的名称。如果GetProcAddress()失败,则失败计数器递增。
if (!(hexdump = (_hexdump)GetProcAddress(h, "hexdump"))) --iFail;
所以,假设我想用宏来替换上面的每一行,就像这样......
GETADDR_FOR(hexdump )
这是迄今为止我提出的最好的。它不起作用(我的//注释只是为了防止消息中的文本格式化)......
// #define GETADDR_FOR(a) if (!(a = (#_#a)GetProcAddress(h, "/""#a"/""))) --iFail;
再一次,虽然我很了解我已经犯下了什么愚蠢的错误,但是只要插入我的宏,它就会让我有一个能够向我展示错误的实用工具。
答案 0 :(得分:23)
转到https://godbolt.org/。在左窗格中输入您的代码,然后选择编译器作为gcc,将参数设置为右窗格中的-E。您的预处理代码将显示在右侧。
答案 1 :(得分:22)
您可以通过预处理器运行代码,预处理器将显示它将被扩展为什么(或根据需要吐出错误):
$ 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 uses /P
参数。
答案 2 :(得分:6)
http://visualstudiogallery.msdn.microsoft.com/59a2438f-ba4a-4945-a407-a1a295598088 - 用于扩展宏的visual studio插件
答案 3 :(得分:2)
您似乎对C预处理器宏中字符串化或令牌粘贴的确切语法感到困惑。
您可能会发现此页面有关C preprocessor macros in general的帮助。
特别是,我认为这个宏应该是这样的:
#define GETADDR_FOR(a) if (!(a = (_##a)GetProcAddress(h, #a))) --iFail
应该跳过尾随;
,因为您可能会将其键入GETADDR_FOR(hexdump);
,如果不这样,它会在您的C代码中看起来很奇怪并且会混淆许多语法高亮显示。
正如其他人提到的那样gcc -E
将运行预处理器并跳过其他编译步骤。这对于调试预处理器问题非常有用。
答案 4 :(得分:1)
您可能需要查看Boost Wave。像大多数Boost一样,它实际上更像是一个库而不是一个实用程序,但它确实有一个驱动程序可以作为一个完整的预处理器。