I know I can do this:
#define MACRO(api, ...) \
bool ret = api(123, ##__VA_ARGS__);
This is just an example, it's part of a more complicated solution. The point is that I need to append the variable number of arguments to the first 123. The ## makes the compiler strip out the comma after the 123 argument if no arguments were passed into MACRO.
But now I want to append arguments to api, like so:
#define MACRO(api, ...) \
bool ret = api(__VA_ARGS__##, 456);
Nocando. One solution is to have two macros, MACRO and MACRO_V, say, and make the _V version not process any arguments. But is there a way to make it work with one macro?
Well, I think it is possible with something like this:
Haven't check it, however should work in latest VS and gcc.
Yes, you can. The following supports up to 4 arguments, but it can be trivially expanded to support more:
This same trick is used to:
Explanation
VA_COMMA
surrounds its arguments (__VA_ARGS__
) with six additional arguments: one empty argument before (doesn't have to be empty—it's thrown away) and four commas and an empty argument after.These six or more arguments are passed to
GET_6TH_ARG
, which, as its name implies, expands to the sixth argument. All other arguments are discarded.Thus,
MACRO(foo)
is expanded like this:MACRO(foo,1)
is expanded like this:MACRO(foo,1,2)
is expanded like this:MACRO(foo,1,2,3,4,5)
is expanded like this:No. The behaviour of
##
which allows this to work in the first case is a GCC extension (C99 does not allow the variable argument part to be empty), and it specifically applies to the case with a comma on the left and__VA_ARGS__
on the right. See e.g. http://gcc.gnu.org/onlinedocs/gcc-4.5.1/gcc/Variadic-Macros.html#Variadic-Macros (at the bottom of the page).