0

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.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
David Ranieri
  • 39,972
  • 7
  • 52
  • 94
  • 1
    Have you tried to run the preprocessor and look at the output? `cpp` or `gcc -E` in GCC. – effeffe Jan 02 '13 at 13:19
  • @effeffe Yes, see edit with cpp output – David Ranieri Jan 02 '13 at 13:25
  • 1
    instead of `, __VA_ARGS__`, you may want to use `, ## __VA_ARGS__`. –  Jan 02 '13 at 13:27
  • @H2CO3, thank you, now it compile and works fine, but warning is still there :( – David Ranieri Jan 02 '13 at 13:43
  • @H2CO3 can you post as comment for accept you answer? warning is : ISO C99 requires rest arguments to be used (with -pedantic on) – David Ranieri Jan 02 '13 at 14:00
  • 1
    @DavidRF I tried to compile the code you pasted (with the `##` prepended to `__VA_ARGS__`) with `gcc file.c -std=c99` and I didn't get any warning. With `-pedantic` I get the same warning (on the rest arguments to be used); but it compiles fine... – 7heo.tk Jan 02 '13 at 14:47
  • 1
    @DavidRF It's practically safe to ignore the warning here. –  Jan 02 '13 at 14:49

1 Answers1

3

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.