可变参数宏, 那些事
同样直接看下面工程中用的示例
//4.0 控制台打印错误信息, fmt必须是双引号括起来的宏
#ifndef CERR
#define CERR(fmt, ...) \
fprintf(stderr,"[%s:%s:%d][error %d:%s]" fmt "\r\n",\
__FILE__, __func__, __LINE__, errno, strerror(errno),##__VA_ARGS__)
#endif/* !CERR */
//4.1 控制台打印错误信息并退出, t同样fmt必须是 ""括起来的字符串常量
#ifndef CERR_EXIT
#define CERR_EXIT(fmt,...) \
CERR(fmt,##__VA_ARGS__),exit(EXIT_FAILURE)
#endif/* !ERR */
#ifndef IF_CERR
/*
*4.2 if 的 代码检测
*
* 举例:
* IF_CERR(fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP), "socket create error!");
* 遇到问题打印日志直接退出,可以认为是一种简单模板
* code : 要检测的代码
* fmt : 必须是""括起来的字符串宏
* ... : 后面的参数,参照printf
*/
#define IF_CERR(code, fmt, ...) \
if((code) < 0) \
CERR_EXIT(fmt, ##__VA_ARGS__)
#endif //!IF_CERR
#ifndef IF_CHECK
/*
* 是上面IF_CERR 的简化版很好用
*/
#define IF_CHECK(code) \
if((code) < 0) \
CERR_EXIT(#code)
#endif // !IF_CHECK
那 传说中的 3颗痣, 就是可变参数宏的一切o(∩_∩)o
|