Variadic Arguments in C Macros

By on

It is possible to wrap a variadic function in C, using some facilities provided by C99 (as supported by GCC and a couple of other compilers). This may be helpful for instance if you need to customize the way you are logging events.


We will try to define our own logger using vfprintf, adding the line and file to the output, using the following macro:

#define LOG(...)        log_print(__LINE__, __FILE__, __VA_ARGS__)

The list of argument used when calling LOG can be of an undefined size, and will be textually replaced by the __VA_ARGS__ macro. That means the following lines produce the same result:

LOG("the answer to life is %d", 42);
log_print(__LINE__, __FILE__, "the answer to life is %d", 42);


Let’s implement the log_print function, a simple printf wrapper:

#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
log_print(int line, char *file, char *fmt, ...)
  va_list       ap;
  fprintf(stdout, "[%s - line %d] ", file, line);
  va_start(ap, fmt);
  vfprintf(stdout, fmt, ap);
  fprintf(stdout, "\n");
  return 0;


Now we can log our debugs with informations about location of the problem, as if we were using a standard printf call:

#include <stdio.h>
#include <errno.h>
#include <string.h>
#define LOG(...)        log_print(__LINE__, __FILE__, __VA_ARGS__)
    FILE *fh;
    if ((fh = fopen("bleh", "r")) == NULL)
        LOG("unable to open file [%s] : %s", bleh, strerror(errno));
    return (0);

An example of output:

$ ./a.out 
[test.c - line 35] unable to open file [/bleh] : No such file or directory