Why does this variadic argument count macro fail with VC++?

后端 未结 2 1030
后悔当初
后悔当初 2020-12-17 10:22

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

相关标签:
2条回答
  • 2020-12-17 11:15

    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.

    0 讨论(0)
  • 2020-12-17 11:23

    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))
    
    0 讨论(0)
提交回复
热议问题