Question

This code works as expected when all params are passed to HTML_A:

#include <stdio.h>

#define HTML_A_fmt_void
#define HTML_A_arg_void
#define HTML_A_fmt_link(fmt, ...) " href=\""fmt"\""
#define HTML_A_arg_link(fmt, ...) ,__VA_ARGS__
#define HTML_A_fmt_text(fmt, ...) fmt
#define HTML_A_arg_text(fmt, ...) ,__VA_ARGS__
#define HTML_A(link, text) \
    printf("<a" HTML_A_fmt_##link ">" HTML_A_fmt_##text "</a>\n" HTML_A_arg_##link HTML_A_arg_##text)

int main(void)
{
    HTML_A(
        link("%s", "http://wwww.google.com"),
        text("%s", "Visit google")
    );
    HTML_A(
        link("%s", "http://wwww.google.com"),
        void
    );
    HTML_A(
        void,
        text("%s", "Visit google")
    );
    HTML_A(
        void,
        void
    );
    return 0;
}

But if I want to call HTML_A without args in format:

HTML_A(
    link("http://wwww.google.com"),
    text("Visit google")
);

I receive this compile error under gcc:

demo.c:17:1: warning: ISO C99 requires rest arguments to be used
demo.c: In function ‘main’:
demo.c:17: error: expected expression before ‘,’ token

cpp returns:

printf("<a" " href=\"""http://wwww.google.com""\"" ">" "Visit google" "</a>\n" , ,);

With ,, at the end.

Was it helpful?

Solution

In order the preprocessor to work correctly, you have to use the concatenation "operator" (which has a special meaning in this context): instead of

, __VA_ARGS__

write

, ## __VA_ARGS__

and it should work as expected.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top