可变参数宏, 那些事
同样直接看下面工程中用的示例
- //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
|