Home Variadic Macros
Post
Cancel

Variadic Macros

Variadic Macros

macro can be declared to accept a variable number of arguments much as a function can

1
#define eprintf(...) fprintf (stderr, __VA_ARGS__)

If your macro is complicated, you may want a more descriptive name for the variable argument than __VA_ARGS__. CPP permits this, as an extension. You may write an argument name immediately before the ‘…’; that name is used for the variable argument. The eprintf macro above could be written

1
#define eprintf(args...) fprintf (stderr, args)

C++20 introduces the __VA_OPT__ function macro. This macro may only appear in the definition of a variadic macro. If the variable argument has any tokens, then a __VA_OPT__ invocation expands to its argument; but if the variable argument does not have any tokens, the __VA_OPT__ expands to nothing:

1
2
#define eprintf(format, ...) \
  fprintf (stderr, format __VA_OPT__(,) __VA_ARGS__)

Furthermore, if you left the variable argument empty, you would have gotten a syntax error, because there would have been an extra comma after the format string.

1
2
eprintf("success!\n", );
     → fprintf(stderr, "success!\n", );

Historically, GNU CPP has also had another extension to handle the trailing comma: the ‘##’ token paste operator has a special meaning when placed between a comma and a variable argument. Despite the introduction of __VA_OPT__, this extension remains supported in GNU CPP, for backward compatibility. If you write

1
#define eprintf(format, ...) fprintf (stderr, format, ##__VA_ARGS__)

and the variable argument is left out when the eprintf macro is used, then the comma before the ‘##’ will be deleted.This does not happen if you pass an empty argument, nor does it happen if the token preceding ‘##’ is anything other than a comma.

This post is licensed under CC BY 4.0 by the author.