我有一个使用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打印一件事,而在另一地方,我将使用X宏的另一列TABLE创建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") \ ^
答案 0 :(得分:1)
在X
扩展前未定义STUFF
会导致…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
答案 1 :(得分:1)
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
。这与通过操纵STUFF
的定义使X
扩展所需的内容相反。
这可以通过更改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)