A variadic macro is a function-like C preprocessor macro whose parameter list ends with ..., allowing an invocation to provide additional arguments. The expansion accesses those arguments through __VA_ARGS__. For example, TRACE_PRINT6("a collection: %g, %i", sum, argc) forwards the format and variable arguments to a printing operation. section 17.4.1
Allowing an empty argument list
A macro that expands directly to a call such as printf(F, __VA_ARGS__) is invalid when no variable arguments are supplied, because the resulting call contains an empty argument after the comma. C23's __VA_OPT__(,) inserts the comma only when __VA_ARGS__ is nonempty, so one macro can support both TRACE_PRINT8("a collection: %g, %i", sum, argc) and TRACE_PRINT8("another string"). section 17.4.1
Important properties and constraints include:
- Place ... at the end of the parameter list; the fixed parameters precede the variable argument list. section 17.4.1
- Stringify __VA_ARGS__ when the textual representation of the complete argument list, including separating commas, is needed. section 17.4.1
- Use __VA_OPT__ with token pasting to select different target macros for calls with two versus three or more arguments. section 17.4.1
- Keep format specifiers consistent with the types of the variable arguments; the macro does not remove the checking burden of formatted output. section 17.4.1
- Prefer an inline function when a fixed number of typed arguments is sufficient; macro programming can obfuscate code and requires restrictive rules. section 17.0
TRACE_PRINT8("a collection: %g, %i", sum, argc);
TRACE_PRINT8("another string");
Compare one variadic trace call with arguments against another containing only a format string, then inspect the corresponding output. section 17.4.1

