为了让编译器满意,我必须计算传递给A()
的params,否则当学习标志打开时gcc会引发“warning: ISO C99 requires rest arguments to be used
”并且只传递一个参数
#include <stdio.h>
/* Count params */
#define N_ARGS(...) N_ARGS_IMPL(__VA_ARGS__,n,n,n,n,n,n,n,n,n,1,1)
#define N_ARGS_IMPL(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,N,...) N
#define A_fmt_void
#define A_arg_void
/* link */
#define A_fmt_link_1(fmt) " href=\""fmt"\""
#define A_fmt_link_n(fmt, ...) " href=\""fmt"\""
#define A_fmt_link_N(n, ...) A_fmt_link_##n(__VA_ARGS__)
#define A_fmt_link_X(n, ...) A_fmt_link_N(n,__VA_ARGS__)
#define A_fmt_link(...) A_fmt_link_X(N_ARGS(__VA_ARGS__), __VA_ARGS__)
#define A_arg_link_1(fmt)
#define A_arg_link_n(fmt, ...) , __VA_ARGS__
#define A_arg_link_N(n, ...) A_arg_link_##n(__VA_ARGS__)
#define A_arg_link_X(n, ...) A_arg_link_N(n,__VA_ARGS__)
#define A_arg_link(...) A_arg_link_X(N_ARGS(__VA_ARGS__), __VA_ARGS__)
/* text */
#define A_fmt_text_1(fmt) fmt
#define A_fmt_text_n(fmt, ...) fmt
#define A_fmt_text_N(n, ...) A_fmt_text_##n(__VA_ARGS__)
#define A_fmt_text_X(n, ...) A_fmt_text_N(n,__VA_ARGS__)
#define A_fmt_text(...) A_fmt_text_X(N_ARGS(__VA_ARGS__), __VA_ARGS__)
#define A_arg_text_1(fmt)
#define A_arg_text_n(fmt, ...) , __VA_ARGS__
#define A_arg_text_N(n, ...) A_arg_text_##n(__VA_ARGS__)
#define A_arg_text_X(n, ...) A_arg_text_N(n,__VA_ARGS__)
#define A_arg_text(...) A_arg_text_X(N_ARGS(__VA_ARGS__), __VA_ARGS__)
/* macro */
#define A(link, text) \
printf("<a"A_fmt_##link">"A_fmt_##text"</a>\n" A_arg_##link A_arg_##text)
int main(void)
{
A(link(), void);
A(void, text());
A(link("http://www.google.es"), void);
A(link("%s/%s", "http://www.google.es", "home"), text("Visit google"));
A(void, text("%s today", "Visit google"));
A(link("http://%s/%s", "www.google.es", "home"), text("%s today", "Visit google"));
A(void,void);
return 0;
}
使用N_ARGS
的这个实现我只能使用10个参数,是否有另一种方法可以检查宏中是否存在多个没有限制的参数?
我知道, ## __VA_ARGS__
gcc扩展名,但我想避免警告
答案 0 :(得分:1)
最后我使用__ extension__
#include <stdio.h>
#define A_fmt_void
#define A_arg_void
#define A_fmt_link(fmt, ...) " href=\""fmt"\""
#define A_arg_link(fmt, ...) , ## __VA_ARGS__
#define A_fmt_text(fmt, ...) fmt
#define A_arg_text(fmt, ...) , ## __VA_ARGS__
#define A(link, text) \
__extension__ printf("<a" A_fmt_##link ">" A_fmt_##text "</a>\n" A_arg_##link A_arg_##text)
int main(void)
{
A(
link("%s", "http://wwww.google.com"),
text("%s", "Visit google")
);
A(
link("http://wwww.google.com"),
void
);
A(
void,
text("Visit google")
);
A(
void,
void
);
return 0;
}
这可以防止在迂腐标志开启时发出警告:)