You can define a variadic macro in C++ like:
#define FOO(x, ...) bar(x, __VA_ARGS__)
But calling FOO as FOO(1) results in the macro expansion bar(1,) which is obviously a syntactical error and won't compile.
Therefore GCC includes a GNU extension:
#define FOO(x, ...) bar(x, ##__VA_ARGS__)
which would expand the given example to the desired result bar(1). Although __VA_ARGS__ is a GNU extension it's support by clang too, but which emits a warning under the -pedantic flag:
warning: token pasting of ',' and __VA_ARGS__ is a GNU extension [-Wgnu-zero-variadic-macro-arguments].
Therefore C++20 includes a new mechanism to achieve the desired result in a standard compliant way:
#define FOO(x, ...) bar(x __VA_OPT__(,) __VA_ARGS__)
This will add the , only if the following __VA_ARGS__ are not empty, otherwise it will omit the ,. This new extension currently works with the GCC and clang trunks (with the -std=c++2a flag enabled): https://godbolt.org/z/k2nAE6.
My only problem is that clang emits a warning under -pedantic:
warning: must specify at least one argument for '...' parameter of variadic macro [-Wgnu-zero-variadic-macro-arguments] (GCC does not emit a warning).
But why? This only seems to make sense if someone only uses __VA_ARGS__ and passes no arguments to the macro. But with the new extension __VA_OPT__ I explicitly handle the case for which no argument is given.
So why would clang emit a warning in this case and how can I work around it?