C macro, wrong argument number returned
c, c-preprocessor
Solution
The problem is that when you pass two arguments to `FOR_EACH` (just the `what` and `x`), the `__VA_ARGS__` expands to nothing, and you have a trailing comma in the call to `FOR_EACH_NARG`, so it expands to 2 and therefore expands `FOR_EACH_2`.
You want to get rid of that trailing comma. You can do that by either using the non-standard extension of using `##__VA_ARGS__` instead of `__VA_ARGS__`, which removes the comma before it only if `__VA_ARGS__` is empty. For a more standards-compliant version, you can combine the `x` and `__VA_ARGS__` into a single parameter:
#define FOR_EACH_(N, what, ...) CONCATENATE(FOR_EACH_, N)(what, __VA_ARGS__)
#define FOR_EACH(what, ...) FOR_EACH_(FOR_EACH_NARG(__VA_ARGS__), what, __VA_ARGS__)
Problem
I have following macros: ``` #define CONCATENATE(arg1, arg2) arg1##arg2 #define FOR_EACH_1(what, x, ...) what(x) #define FOR_EACH_2(what, x, ...) what(x) FOR_EACH_1(what, __VA_ARGS__) #define FOR_EACH_3(what, x, ...) what(x) FOR_EACH_2(what, __VA_ARGS__) #define FOR_EACH_4(what, x, ...) what(x) FOR_EACH_3(what, __VA_ARGS__) #define FOR_EACH_5(what, x, ...) what(x) FOR_EACH_4(what, __VA_ARGS__) #define FOR_EACH_6(what, x, ...) what(x) FOR_EACH_5(what, __VA_ARGS__) #define FOR_EACH_7(what, x, ...) what(x) FOR_EACH_6(what, __VA_ARGS__) #define FOR_EACH_8(what, x, ...) what(x) FOR_EACH_7(what, __VA_ARGS__) #define FOR_EACH_NARG(...) FOR_EACH_NARG_(__VA_ARGS__, FOR_EACH_RSEQ_N()) #define FOR_EACH_NARG_(...) FOR_EACH_ARG_N(__VA_ARGS__) #define FOR_EACH_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, N, ...) N #define FOR_EACH_RSEQ_N() 8, 7, 6, 5, 4, 3, 2, 1, 0 #define FOR_EACH_(N, what, x, ...) CONCATENATE(FOR_EACH_, N)(what, x, __VA_ARGS__) #define FOR_EACH(what, x, ...) FOR_EACH_(FOR_EACH_NARG(x, __VA_ARGS__), what, x, __VA_ARGS__) ``` These are my test cases: ``` // does not work as intended (with one argument) #define SOME(x) int x; FOR_EACH(SOME, y) // fine with 2 and more FOR_EACH(SOME, y1, y2); FOR_EACH(SOME, y3, y4, y5, y6); // works fine even for one argument #define ONLY(x) x int FOR_EACH(ONLY, x); ``` Could please someone explain to me what I'm doing wrong for the case with only one argument, `#define SOME(x) int x`?? Compile it with `gcc -E macro.c -o macro.lol`, gives result: ``` int y; int ; /* <-- that's wrong, why??? */ int y1; int y2;; int y3; int y4; int y5; int y6;; int x ; /* <-- works as supposed */ ```