繁体   English   中英

在另一个宏中展开 X 宏

[英]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 宏必须在它展开的地方适当地定义。 它根本不需要在它出现在另一个宏的扩展文本中的地方定义。 你好像落后了。


正如评论中所讨论的,目标是能够定义单独的宏,例如STUFFSTUFF2TABLE扩展为彼此不同的一致结果。 这与通过操纵X的定义使STUFF根据需要扩展相反。

这可以通过更改TABLE的定义来实现,使其成为一个类似函数的宏,以另一个宏名称作为参数:

#define TABLE(m) \
    m("abc", "123", "ddd") \
    m("def", "456", "aaa") \
    m("ghi", "789", "ddd")

然后,宏STUFFSTUFF2可以通过选择将哪个宏名称传递给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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM