目录

C++变参宏的一个跨平台兼容问题


目录

由一个尾部逗号的问题,会引发不同平台编译器对变参宏的展开的问题,比如如下的一个例子:

#define NEW_LOG(formatmsg, ...) fprintf(stdout, "%s(%u): " formatmsg "\n", __FILE__, __LINE__, __VA_ARGS__)

如果传一个可变参数,则编译正常

NEW_LOG("test for num: %d", 100);

这时候宏展开是这样的

fprintf(stdout, "%s(%u): test for num: %d\n", __FILE__, __LINE__, 100)

但是如果不传可变参,我们这样调用宏

NEW_LOG("test no args")

这时候不同编译器的展开就不一样了,clang和gcc是这么展开的

frpintf(stdout, "%s(%u): test no args\n", __FILE__, __LINE__, )

末尾会多出一个逗号,导致编译错误。 而微软的cl就可以正常处理掉这个逗号正常编译。

所以如何正确的写出跨平台的宏变参呢,在__VA_ARGS__前面加##就可以正确处理了,这里的问题倒更像gcc中存在的一个bug,如上的宏应该写成下面这样:

#define NEW_LOG(formatmsg, ...) fprintf(stdout, "%s(%u): " formatmsg "\n", __FILE__, __LINE__, ##__VA_ARGS__)