宏定义的巧用

1. #用来标记参数是字符串

#define STRING(X) #X
const char *str = STRING(test);
cout << str << endl;

这里str的内容就是"test"

2. ##用来连接参数

#define AND(X) X##X
int num = AND(8);
cout << num << endl;

这里num的内容就是88

3. __VA_ARGS__可变参数宏

#define PRINTF_ERROR(format, ...) \
        printf("[%s %s] [ERROR] %s:%d %s() " format" errno:%d err:%s\n", \
        __DATE__, __TIME__, __FILE__, __LINE__,	__FUNCTION__, \
        ##__VA_ARGS__, errno, strerror(errno))
PRINTF_ERROR("test::print %s %s", str1, str2);

format照写,__VA_ARGS__是系统预定义宏,代表了...这个可变参数列表。

其实在gcc中还支持可变参数名

#define PRINTF_ERROR(format, args...) \
        printf("[%s %s] [ERROR] %s:%d %s() " format" errno:%d err:%s\n", \
        __DATE__, __TIME__, __FILE__, __LINE__,	__FUNCTION__, \
        ##args, errno, strerror(errno))
PRINTF_ERROR("test::print %s %s", str1, str2);

这样可以用args代替可变参数列表...

这里__VA_ARGS__和args前面都带上了##,是因为如果你使用PRINTF_ERROR,却没有可变参数,例如

PRINTF_ERROR("server start success");

就会编译报错。为了兼容有可变参数和没有可变参数的情况,加上了##

细心的会发现format和前面的引号之间有空格,这是因为C++11告警invalid suffix on literal; C++11 requires a space between literal and identifier [-Wliteral-suffix]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章