Short explanation because I take from the comments that this was cargo-culted into the code: The ##
in ##__VA_ARGS__
is a non-standard extension of the preprocessor (originally from gcc, now also supported by clang). Its effect is that if a variadic macro is called with no variadic parameters, a superfluous preceding comma is removed. That is to say, where
#define FOO(bar, ...) foo(bar, __VA_ARGS__)
cannot be called with one argument because it would expand to foo(argument,)
,
#define FOO(bar, ...) foo(bar, ##__VA_ARGS__)
can because the comma is silently removed and the expansion is foo(argument)
.
Therefore, the solution to your problem is to use
// vv--- these are important here
#define OUT(fmt, ...) LOG(stdout, fmt, ##__VA_ARGS__)
Otherwise in an expansion of OUT
with only one argument, the __VA_ARGS__
in LOG
will not be empty because it is expanded from
LOG(stdout, "Hello, world.",)
instead of
LOG(stdout, "Hello, world.")
...and the ##
before __VA_ARGS__
in LOG
will then have no effect. You get the compiler message because there's an extra comma in the expansion of LOG
(the fprintf
call ends with ,)
).
Link to specifics.