2

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.

3
  • 2
    IMO, it looks to be a problem with the compilers rather than your code. Commented Jun 11 at 3:51
  • What happens if you alter the example so that there is an argument for the , ... to work with? Do the compilers process __VA_OPT__ correctly then? Commented Jun 11 at 5:53
  • @JonathanLeffler Yes, works fine then: godbolt.org/z/7f6n81MvY
    – Harith
    Commented Jun 11 at 7:11

1 Answer 1

1

Your code is fine, this appears to be a diagnostic bug in clang 18.1 (and icx is basically clang too).

Not the answer you're looking for? Browse other questions tagged or ask your own question.