cmacrosvariadic-macros

variadic format strings in C macros?


I'm trying to write a basic macro like this:

#define USER_ERROR(fmt, ...) { \
    fprintf(stderr, "ERROR %s(): %s\n", __func__, fmt, ##__VA_ARGS__); \
} \

my ideal usage:

USER_ERROR("something went wrong %s %s", more_detail, even_more_detail);

unfortunately, I'm getting a compilation error:

data argument not used by format string

I know that single %s handles one argument, but how can I make the formatter variadic?


Solution

  • You can use string constant concatenation to combine your format string with the built-in one in your macro:

    #define USER_ERROR(fmt, ...) \
        fprintf(stderr, "ERROR %s(): " fmt "\n", __func__, ##__VA_ARGS__);
    
    int main()
    {
        char more_detail[]="abc", even_more_detail[]="def";
        USER_ERROR("something went wrong %s %s", more_detail, even_more_detail);
        return 0;
    }
    

    Output:

    ERROR main(): something went wrong abc def
    

    This also has the side effect of ensuring that your format string is a string constant, as having a format string potentially under the control of a user can lead to security issues.