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?