在另一个宏中展开 X 宏
Expand X macro inside another macro
我有一个使用 fprintf()
打印输出的函数,它对格式字符串和参数都使用了一个宏。由于有多个地方打印此信息,这允许在仅更改一个地方的同时扩展打印。
我想使用相同的数据生成不同的打印件,但我希望它们使用 X-macro 自动扩展在一起,但我无法编译。我不希望每次添加要打印的内容时都需要编辑打印件,或者将每张打印件包装成丑陋的 #define
s.
此程序尝试执行我想要的操作,但未编译:
#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 宏的不同列做一个 STUFF2,称为 TABLE)
我收到以下错误:
main.c: In function ‘main’:
main.c:7:5: warning: implicit declaration of function ‘X’ [-Wimplicit-function-declaration]
X("abc", "123", "ddd") \
^
main.c:12:5: note: in expansion of macro ‘TABLE’
TABLE
^~~~~
main.c:18:27: note: in expansion of macro ‘STUFF’
printf(" %s %s %s\n", STUFF);
^~~~~
main.c:8:5: error: expected ‘)’ before ‘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: warning: implicit declaration of function ‘X’ [-Wimplicit-function-declaration]
嗯,是的。在第18行,出现宏STUFF
的地方,首先展开为
TABLE
,那就是重新扫描。 TABLE
被定义为宏,它也被扩展,导致
X("abc", "123", "ddd") X("def", "456", "aaa") X("ghi", "789", "ddd")
,然后 那个 被重新扫描。但是 X
不是 定义为宏(或其他任何东西),因为您之前 undef
ined 它。剩下的代码类似于对未知函数的三次调用,中间没有任何类型的运算符或分隔符。无效。
你的 X 宏必须在它展开的地方适当地定义。它根本不需要在它出现在另一个宏的扩展文本中的地方定义。你好像有点落后了。
正如评论中所讨论的那样,objective 能够定义单独的宏,例如 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)
我有一个使用 fprintf()
打印输出的函数,它对格式字符串和参数都使用了一个宏。由于有多个地方打印此信息,这允许在仅更改一个地方的同时扩展打印。
我想使用相同的数据生成不同的打印件,但我希望它们使用 X-macro 自动扩展在一起,但我无法编译。我不希望每次添加要打印的内容时都需要编辑打印件,或者将每张打印件包装成丑陋的 #define
s.
此程序尝试执行我想要的操作,但未编译:
#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 宏的不同列做一个 STUFF2,称为 TABLE)
我收到以下错误:
main.c: In function ‘main’:
main.c:7:5: warning: implicit declaration of function ‘X’ [-Wimplicit-function-declaration]
X("abc", "123", "ddd") \ ^
main.c:12:5: note: in expansion of macro ‘TABLE’
TABLE ^~~~~
main.c:18:27: note: in expansion of macro ‘STUFF’
printf(" %s %s %s\n", STUFF); ^~~~~
main.c:8:5: error: expected ‘)’ before ‘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: warning: implicit declaration of function ‘X’ [-Wimplicit-function-declaration]
嗯,是的。在第18行,出现宏STUFF
的地方,首先展开为
TABLE
,那就是重新扫描。 TABLE
被定义为宏,它也被扩展,导致
X("abc", "123", "ddd") X("def", "456", "aaa") X("ghi", "789", "ddd")
,然后 那个 被重新扫描。但是 X
不是 定义为宏(或其他任何东西),因为您之前 undef
ined 它。剩下的代码类似于对未知函数的三次调用,中间没有任何类型的运算符或分隔符。无效。
你的 X 宏必须在它展开的地方适当地定义。它根本不需要在它出现在另一个宏的扩展文本中的地方定义。你好像有点落后了。
正如评论中所讨论的那样,objective 能够定义单独的宏,例如 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)