An important fact about C/C++ macros is that it is impossible to invoke them with no parameters, because a macro parameter is allowed to be an empty token sequence.
Consequently, DUMMY()
invokes the macro DUMMY
with a single empty parameter, not with zero parameters. This explains why the second example works, and it also explains why the first example produces a syntax error.
The GCC extension deletes the comma from , ##__VA_ARGS__
when __VA_ARGS__
has no elements. But a single empty argument is not the same as no arguments. When you define DUMMY
as #define DUMMY(...)
, you are guaranteeing that __VA_ARGS__
has at least one argument, so the ,
won't be deleted.
***Note: GCC does make an exception to that rule if you don't specify some ISO standard with the --std
option. In that case, if ...
is the only macro parameter and the invocation has an empty argument, then ,##__VA_ARGS__
does drop the comma. This is noted in the CPP manual in the Variadic Marcos section:
The above explanation is ambiguous about the case where the only macro parameter is a variable arguments parameter, as it is meaningless to try to distinguish whether no argument at all is an empty argument or a missing argument. CPP retains the comma when conforming to a specific C standard. Otherwise the comma is dropped as an extension to the standard.
When DUMMY
is #define DUMMY(x, ...)
, __VA_ARGS
will be empty if DUMMY
is invoked with only one argument, which includes both the invocations DUMMY()
(one empty argument) and DUMMY(0)
(one argument, 0
). Note that standard C, and C++ until C++20, would not allow this invocation; they require that there be at least one (possibly empty) argument corresponding to the ellipsis. GCC never imposed this restriction, though, and GCC will omit the comma with ,##__VA_ARGS__
regardless of the --std
setting.
Starting with C++20, you can use the __VA_OPT__
built-in macro as a more standard way of dealing with commas (and any other punctuation which might need to be deleted). __VA_OPT__
also avoids the problem presented above with empty arguments, because it uses a different criterion: __VA_OPT__(x)
expands to x
if __VA_ARGS__
contains at least one token; otherwise, it expands to an empty sequence. Consequently, __VA_OPT__
would work as expected for the macros in this question.
I believe that all major compilers now implement __VA_OPT__
, at least in their recent versions.