Reputation: 1103
I am writing a "mapping macro" and want to use it to generate enums, classes, function calls ...
This is how the macro looks like:
#define MY_MAPPING(ENTRY) \
ENTRY(a, {0x10,0x01,0x01,0x00}, foo) \
ENTRY(b, {0x10,0x01,0x02,0x00}, boo)
Now I am trying to generate an enumeration using the "mapping macro"
#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;
I am getting the error: macro "EXPAND_TO_ENUM" passed 6 arguments, but takes just 3
.
The reason is the elements between brackets, the compiler is considering each element into the bracket as a single element Why and do you have any Idea to solve the problem?
Of course using parentheses will solve the problem but I don't want to use them since I need to use the elements between brackets as function arguments after for foo
and boo
, they are accepting array as input.
Upvotes: 1
Views: 86
Reputation: 2674
I am getting the error: macro "EXPAND_TO_ENUM" passed 6 arguments, but takes just 3. The reason is the elements between brackets, the compiler is considering each element into the bracket as a single element Why
Macros are processed by the preprocessor, not the "language proper". A function-like macro invocation recognizes string-boundaries and will match parentheses, but not braces or square brackets... to the preprocessor, [
, {
, }
, and ]
are just tokens having nothing to do with each other. (Incidentally, the name for the thing you're writing is an X-macro).
When you invoke MY_MAPPING(something)
, assuming that something
"expands" to a token that's #define
'd as a function-like macro, then once this part is evaluated:
ENTRY(a, {0x10,0x01,0x01,0x00}, foo)
...it will be a macro invocation with six arguments:
a
{0x10
0x01
0x01
0x00}
foo
do you have any Idea to solve the problem?
Part 1 of the solution: Use parentheses. If you use parentheses (the preprocessor does match those):
ENTRY(a, (0x10, 0x01, 0x01, 0x00), foo)
...then your invocation has three arguments:
a
(0x10, 0x01, 0x10, 0x00)
foo
Part 2 is implied:
they are accepting array as input.
...but I can't figure out what you're really saying here, other than that somehow you want that argument 2 to be surrounded by braces. That you can do easily enough:
#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)
...expands to:
int a[] = { 0x10,0x01,0x01,0x00 }; int b[] = { 0x10,0x01,0x02,0x00 };
Upvotes: 2