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