宏中的参数数量

时间:2018-09-12 07:28:52

标签: c macros

我正在编写“映射宏”,并希望使用它来生成枚举,类,函数调用...

这是宏的样子:

#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。 原因是括号之间的元素,编译器正在将括号中的每个元素视为单个元素。为什么并且您有任何想法可以解决问题?

当然使用括号可以解决问题,但是我不想使用它们,因为在fooboo之后,我需要使用方括号之间的元素作为函数参数,因为它们接受数组作为输入。

1 个答案:

答案 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)