I'm writing a variadic dispatcher macro in C++, to call a different macro based on the number of arguments (from none up to 5) provided to the dispatcher. I came up with this solution:
#define GETOVERRIDE(_ignored, _1, _2, _3, _4, _5, NAME, ...) NAME
#define NAMEDARGS(...) GETOVERRIDE(ignored, ##__VA_ARGS__, NAMEDARGS5, NAMEDARGS4, NAMEDARGS3, NAMEDARGS2, NAMEDARGS1, NAMEDARGS0)(__VA_ARGS__)
NAMEDARGS is the dispatcher macro; calling it with 1 argument will result in a call to NAMEDARGS1 which takes 1 argument, and so on (I don't provide the implementations of the various NAMEDARGS# since they are irrelevant in this context).
I tested the code gcc 7.1.1, and I found a weird behavior of the gcc expansion when using the -std=c++14 flag. With this test code:
NAMEDARGS()
NAMEDARGS(int)
NAMEDARGS(int, float)
I get these expansions:
$ gcc -E testMacro.cpp
NAMEDARGS0()
NAMEDARGS1(int)
NAMEDARGS2(int, float)
$ gcc -E -std=c++14 testMacro.cpp
NAMEDARGS1()
NAMEDARGS1(int)
NAMEDARGS2(int, float)
It seems that using the -std=c++14 flag the substitution of the zero-argument call fails, resulting in the call of the one-argument macro. I thought that this could be because the ##__VA_ARGS__ syntax is a GNU extension, thus not working with an ISO C++ preprocessor; however, when trying with clang 4.0.1 I obtain the desired expansion:
$ clang -E -std=c++14 testMacro.cpp
NAMEDARGS0()
NAMEDARGS1(int)
NAMEDARGS2(int, float)
So I don't understand what's going on here. Does clang implement this gnu extension, accepting non-ISO code also with -std==c++14 unlike gcc? Or maybe the problem lies elsewhere? Thanks for the help.