[英]Expand X macro inside another macro
我有一个使用fprintf()
打印输出的函数,它使用一个宏来处理格式字符串和参数。 由于有多个位置打印此信息,因此可以在仅更改一个位置的同时扩展打印。
我想使用相同的数据生成不同的打印,但我希望它们使用 X 宏自动扩展在一起,但我无法编译它。 我不希望每次添加要打印的内容时都需要编辑打印,或者将每个打印都包裹在丑陋的#define
。
这个程序试图做我想做的事,但它不编译:
#include <stdio.h>
#define X(_a, _b, _c) \
_a,
#define TABLE \
X("abc", "123", "ddd") \
X("def", "456", "aaa") \
X("ghi", "789", "ddd") \
#define STUFF \
TABLE
#undef X
int main()
{
printf(" %s %s %s\n", STUFF);
return 0;
}
(想法是 STUFF 打印一件事,在另一个地方,我将使用名为 TABLE 的 X 宏的不同列执行 STUFF2)
我收到以下错误:
main.c:在函数“main”中:
main.c:7:5: 警告:函数“X”的隐式声明 [-Wimplicit-function-declaration]
X("abc", "123", "ddd") \\ ^
main.c:12:5: 注意:在宏 'TABLE' 的扩展中
TABLE ^~~~~
main.c:18:27: 注意:在宏 'STUFF' 的扩展中
printf(" %s %s %s\\n", STUFF); ^~~~~
main.c:8:5: 错误:'X' 之前的预期 ')'
X("def", "456", "aaa") \\ ^
在扩展STUFF
之前取消定义X
会导致……好吧X
未定义。
要使 X 宏工作,您必须在某些非宏代码中使用它后取消定义(以便它可以扩展)
修复此问题后,需要在列表中移动逗号,否则最后一个逗号将触发语法错误( error: expected ')' before 'X'
)。 TABLE
的最后一个反斜杠也是如此
#include <stdio.h>
#define X(_a, _b, _c) \
_a
#define TABLE \
X("abc", "123", "ddd"), \
X("def", "456", "aaa"), \
X("ghi", "789", "ddd")
#define STUFF \
TABLE
int main()
{
printf(" %s %s %s\n", STUFF);
#undef X
return 0;
}
这将编译、执行并打印abc def ghi
main.c:7:5: 警告:函数“X”的隐式声明 [-Wimplicit-function-declaration]
嗯,是。 在第 18 行,宏STUFF
出现的地方,它首先被扩展为
TABLE
,然后重新扫描。 TABLE
被定义为一个宏,它也被扩展,导致
X("abc", "123", "ddd") X("def", "456", "aaa") X("ghi", "789", "ddd")
,那么重新扫描。 但此时X
并未定义为宏(或其他任何内容),因为您之前undef
它。 这使您的代码类似于对未知函数的三个调用,之间没有任何类型的运算符或分隔符。 它是无效的。
你的 X 宏必须在它展开的地方适当地定义。 它根本不需要在它出现在另一个宏的扩展文本中的地方定义。 你好像落后了。
正如评论中所讨论的,目标是能够定义单独的宏,例如STUFF
和STUFF2
将TABLE
扩展为彼此不同的一致结果。 这与通过操纵X
的定义使STUFF
根据需要扩展相反。
这可以通过更改TABLE
的定义来实现,使其成为一个类似函数的宏,以另一个宏名称作为参数:
#define TABLE(m) \
m("abc", "123", "ddd") \
m("def", "456", "aaa") \
m("ghi", "789", "ddd")
然后,宏STUFF
和STUFF2
可以通过选择将哪个宏名称传递给TABLE()
来控制扩展:
#define X(_a, _b, _c) _a
#define Y(_a, _b, _c) _b
#define STUFF TABLE(X)
#define STUFF2 TABLE(Y)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.