C99中的变量宏有一个带空参数的well-known problem.
例子:
#define FOO(...) printf(__VA_ARGS__)
#define BAR(fmt, ...) printf(fmt, __VA_ARGS__)
FOO("this works fine");
BAR("this breaks!");
根据C99标准,上述BAR()
的使用确实是不正确的,因为它将扩展到:
printf("this breaks!",);
注意后面的逗号-不可行.
一些编译器(例如:VisualStudio2010)会悄悄地为您go 掉后面的逗号.其他编译器(例如:GCC)支持将##
置于__VA_ARGS__
之前,例如:
#define BAR(fmt, ...) printf(fmt, ##__VA_ARGS__)
但是,有没有一种符合标准的方法来实现这种行为呢? 也许使用多个宏?
目前,##
版本似乎得到了相当好的支持(至少在我的平台上是这样),但我真的更愿意使用符合标准的解决方案.
先发制人:我知道我可以写一个小函数.我正试图用宏来实现这一点.
Edit:下面是一个例子(虽然很简单),说明我为什么要使用BAR()
#define BAR(fmt, ...) printf(fmt "\n", ##__VA_ARGS__)
BAR("here is a log message");
BAR("here is a log message with a param: %d", 42);
这会自动在我的bar()日志(log)语句中添加一个换行符,假设fmt
总是用双引号引起来的C字符串.它不会将换行符作为单独的printf()打印,这在日志(log)记录是行缓冲的并且异步来自多个源的情况下非常有利.