You can define a variadic macro in C like:
#define F(x, ...) f(x, __VA_ARGS__)
But calling F
as F(a)
results in the macro expansion f(a,)
which would not compile.
So C23 includes __VA_OPT__
to achieve the desired result:
#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 ,
.
When I compile the following code:
#include <stdio.h>
#define F(X, ...) 10, X __VA_OPT__(,) __VA_ARGS__
int main(void)
{
printf("%d, %d\n", F(20));
}
with GCC 14.1 with the following flags -O3 -std=c23 -pedantic-errors -Werror -Wall
, there is no problem. But when I compile it with Clang 18.1 or ICX 2024.0 (with the same flags, except for -std=c2x
for ICX), it fails with:
<source>:7:28: error: must specify at least one argument for '...' parameter of variadic macro [-Werror,-Wgnu-zero-variadic-macro-arguments]
7 | printf("%d, %d\n", F(20));
| ^
<source>:3:9: note: macro 'F' defined here
3 | #define F(X, ...) 10, X __VA_OPT__(,) __VA_ARGS__
| ^
1 error generated.
Compiler returned: 1
Is the problem with my code, or have Clang and ICX not updated their warnings?
Aside: I am aware that -Werror
is turning the warning into an error.
, ...
to work with? Do the compilers process__VA_OPT__
correctly then?