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.
Dummy("Hello",);:( coliru. - anton_rh