Site Tools


c-variadic-macros

C variadic macros

C variadic macros (C99) accept a variable number of arguments using __VA_ARGS__. They enable flexible printf-like logging, assertion macros, and generic utilities without separate macro definitions for each argument count.

Use variadic macros for debug logging, flexible error handling, or type-generic operations.

Example

// compile: gcc -std=c99 -o variadic variadic.c
// run: ./variadic
// description: variadic macros for flexible logging
 
#include <stdio.h>
#include <stdlib.h>
 
#define LOG(fmt, ...) \
    do { \
        printf("[LOG] " fmt "\n", __VA_ARGS__); \
    } while(0)
 
#define ERROR(fmt, ...) \
    do { \
        fprintf(stderr, "[ERROR] " fmt "\n", __VA_ARGS__); \
    } while(0)
 
#define ASSERT_MSG(cond, fmt, ...) \
    do { \
        if (!(cond)) { \
            fprintf(stderr, "ASSERT FAILED: " fmt "\n", __VA_ARGS__); \
            exit(1); \
        } \
    } while(0)
 
int main() {
    LOG("Starting program");
    LOG("Value: %d", 42);
    LOG("Name: %s, Age: %d", "Alice", 30);
 
    int x = 10;
    ASSERT_MSG(x > 0, "x must be positive, got %d", x);
 
    printf("Success\n");
    return 0;
}

Common patterns

__VA_ARGS__ expansion:

  • Represents all arguments after comma
  • Includes any nested commas in arguments

Empty argument case:

  • Some compilers require at least one arg
  • Use ##__VA_ARGS__ to handle empty case (removes trailing comma)

Debug macros:

  • Combine with NDEBUG for conditional compilation
  • Printf-style logging without function call overhead

When to use:

  • Logging and debugging
  • Error reporting
  • Generic type utilities
c-variadic-macros.md · Last modified: by 127.0.0.1