I got the following implementation to get the number of arguments in a variadic macro (currently limited to 16 args). However, for VS2010 the output is always 1
, no matter how many arguments are passed. With GCC, the output is correct, bringing me to the conclusion that I must have missed something specific for MSVC (10).
#define PP_NARGS(...) \
_xPP_NARGS_IMPL(__VA_ARGS__,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)
#define _xPP_NARGS_IMPL(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15,N,...) N
int main(){
int i = PP_NARGS(A,V,C,X,Y,Z);
std::cout << i;
std::cin.get();
return 0;
}
So, question is as the title states, any help would be appreciated.
Does the following work-around help?
#define EXPAND(x) x
#define PP_NARGS(...) \
EXPAND(_xPP_NARGS_IMPL(__VA_ARGS__,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0))
I think your macro isn't wrong in particular, but
MSVC's __VA_ARGS__
expansion seems to behave differently from C99.
The problem seems that Visual Studio is expanding __VA_ARGS__
after passing it into the subsequent macro, while gcc expands it before passing.
In your case, PP_NARGS(A,V,C,X,Y,Z)
binds A,V,C,X,Y,Z
to __VA_ARGS__
, and then passes it as a whole to _xPP_NARGS_IMPL
.
As a test, run:
#define PP_NARGS(...) \
_xPP_NARGS_IMPL(__VA_ARGS__,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)
#define _xPP_NARGS_IMPL(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15,N,...) \
(std::cout << #x1 << std::endl, N)
int main() {
int i = PP_NARGS(A, V, C, X, Y, Z);
std::cout << i;
return 0;
}
You will see A, V, C, X, Y, Z
printed on the screen, and not just A
as you would probably expect.
A possible solution, as suggested by Ise Wisteria already, is to force the expansion via:
#define EXPAND(x) x
#define PP_NARGS(...) \
EXPAND(_xPP_NARGS_IMPL(__VA_ARGS__,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With