LINUX C中如何定义可变参数的宏

转载:http://darksun.blog.51cto.com/3874064/1379569


一般在调试打印Debug信息的时候, 需要可变参数的宏. 从C99开始可以使编译器标准支持可变参数宏(variadic macros), 另外GCC也支持可变参数宏, 但是两种在细节上可能存在区别.
1. __VA_ARGS__
__VA_ARGS__ 将 "..." 传递给宏 . 如

#define debug1(...) fprintf(stderr, __VA_ARGS__)
#define debug2(format, ...) fprintf(stderr, format, __VA_ARGS__)


2. GCC的复杂宏

GCC使用一种不同的语法,从而可以给可变参数一个名字,如同其它参数一样.
#define debug1(args...) fprintf(stderr, args)  
#define debug2(format, args...) fprintf(stderr, format, args) 
这和第一条的宏例子是完全一样的,但是这么写可读性更强并且更容易进行描述.

3. ##__VA_ARGS__,  ##args
上面两个定义的宏,如果出现 debug2("A Message")的时候,由于宏展开后有个多余的逗号,所以将导致编译错误.

为了解决这个问题,CPP 使用一个特殊的"##"操作,格式如下:

#define debug3(format, ...) fprintf(stderr, format, ##__VA_ARGS__)
#define debug3(format, args...) fprintf(stderr, format, ##args) 
这里,如果可变参数被忽略或为空,"##"操作将使预处理器(preprocessor)去除掉它前面的那个逗号.

举例:
    debug1("t1");     // print "t1"
    debug2("t2");     // compile error(gcc but vs)
    debug2("t%d", 2); // print "t2"
    debug3("t3");     // print "t3"
    debug3("t%d", 3); // print "t3"


你可能感兴趣的:(C/C++)