可变参数宏, Variadic Macros
说起可变参数,立即想到的就是printf(),scanf()了.可变参数就是有一个固定的格式控制参数,后面再根据格式控制参数接若干参数.
这里先讨论可变参数宏.
我们一般在Debug需要打印调试信息的时候,需要可变参数的宏.
一, vc(C99)的复杂宏.
参考msdn(http://msdn2.microsoft.com/en-us/library/ms177415.aspx ).使用这种复杂宏时,省略号是格式控制参数,而标识符__VA_ARGS__用来插入另外的参数.__VA_ARGS__ 将"..." 传递给宏.
例如:
输出为:
here are some varargs1(1)
here are some varargs2(4)
here are some varargs3(5)
二,GCC中的复杂宏
GCC支持C99中的复杂宏,但G++不支持.GCC使用一种不同的语法,给可变参数一个名字,如同其它参数一样.
#define CHECK1(x,format, args...) if(x) { printf (format, args); }
显然这样易于描述而且可读性更强.
三,CHECK("Some messges.")的情况
这时由于宏展开后有个多余的逗号,,将导致编译错误..为了解决这个问题,CPP使用一个特殊的“##”操作.
#define CHECK(format, ...) printf ( format, ## __VA_ARGS__)
这里,如果可变参数被忽略或为空,“##”操作将使预处理器去除掉它前面的那个逗号.如果在宏调用时,确实提供了一些可变参数,GNU CPP也会工作正常,它会把这些可变参数放到逗号的后面.
四,类似printf()的技巧
用一个被括弧括起来的 “参数”来定义和调用宏,参数在宏扩展的时候成为类似printf()函数中的格式控制字符串那样的参数列表.
#define CHECK(args) (printf("DEBUG: "), printf(args))