我正在编写“映射宏”,并希望使用它来生成枚举,类,函数调用...
这是宏的样子:
#define MY_MAPPING(ENTRY) \
ENTRY(a, {0x10,0x01,0x01,0x00}, foo) \
ENTRY(b, {0x10,0x01,0x02,0x00}, boo)
现在我正在尝试使用“映射宏”生成枚举
#define STRCONC(a,b) a##b
#define EXPAND_TO_ENUM(a,b,c) STRCONC(a,_Idx),
typedef enum
{
MY_MAPPING(EXPAND_TO_ENUM)
}example_Enum;
我收到错误:macro "EXPAND_TO_ENUM" passed 6 arguments, but takes just 3
。
原因是括号之间的元素,编译器正在将括号中的每个元素视为单个元素。为什么并且您有任何想法可以解决问题?
当然使用括号可以解决问题,但是我不想使用它们,因为在foo
和boo
之后,我需要使用方括号之间的元素作为函数参数,因为它们接受数组作为输入。
答案 0 :(得分:2)
我遇到了错误:宏“ EXPAND_TO_ENUM”传递了6个参数,但只接受了3个参数。原因是括号之间的元素,编译器正在将括号中的每个元素视为单个元素,为什么
宏是由预处理器处理的,而不是由“适当的语言”处理的。类似于函数的宏调用会识别字符串边界,并将括号(而不是括号或方括号)与预处理器[
,{
,}
和{{1 }}只是彼此无关的令牌。 (顺便说一句,您正在写的东西的名称是X宏)。
当您调用]
时,假设MY_MAPPING(something)
“扩展”为something
作为类似函数的宏的令牌,那么一旦评估了该部分:
输入 #define
...它将是带有六个参数的宏调用:
(a, {0x10,0x01,0x01,0x00}, foo)
a
{0x10
0x01
0x01
0x00}
您有解决问题的主意吗?
解决方案的第1部分:使用括号。如果使用括号(预处理器匹配),
输入 foo
...然后您的调用具有三个参数:
(a, (0x10, 0x01, 0x01, 0x00), foo)
a
(0x10, 0x01, 0x10, 0x00)
暗示第2部分:
他们接受数组作为输入。
...但是我无法弄清楚您在这里真正说的是什么,除了您希望以某种方式将参数2括在括号中之外。您可以轻松完成:
foo
...扩展到:
#define MY_MAPPING(ENTRY) \
ENTRY(a, (0x10,0x01,0x01,0x00), foo) \
ENTRY(b, (0x10,0x01,0x02,0x00), boo)
#define BRACIFY(...) { __VA_ARGS__ }
#define MAKE_SOME_INT_ARRAY_THINGY(ID, INIT, X) int ID[] = BRACIFY INIT;
MY_MAPPING(MAKE_SOME_INT_ARRAY_THINGY)