以前由於linux平臺,通常編譯調試沒有win平臺調試方便,因此會加大對日誌信息的輸出力度,在將以往一個常使用的打印輸出宏定義遷移到win下才用vs2015編譯時,出現了"宏形參表中的意外"告警,源代碼如下:
#ifndef _PFUNC_PRINT_H_
#define _PFUNC_PRINT_H_
/***********************************************************************
*Copyright 2019-04-16, pyfree
*
*File Name : pfunc_print.h
*File Mark :
*Summary : 打印輸出通用宏定義
*
*Current Version : 1.00
*Author : pyfree
*FinishDate :
*
*Replace Version :
*Author :
*FinishDate :
************************************************************************/
typedef enum PrintLevel
{
LL_NOTICE = 1, //一般輸出
LL_WARNING = 2, //告警輸出
LL_TRACE = 3, //追蹤調試
LL_DEBUG = 4, //軟件bug
LL_FATAL = 5 //致命錯誤
}PrintLevel;
#define Print_NOTICE(log_fmt,log_arg...) \
do{ \
printf("L(%d)[%s:%d][%s] \n"log_fmt"\n", LL_NOTICE,__FILE__, __LINE__, __FUNCTION__, ##log_arg); \
}while (0)
#define Print_WARN(log_fmt,log_arg...) \
do{ \
printf("L(%d)[%s:%d][%s] \n"log_fmt"\n", LL_WARNING, __FILE__, __LINE__, __FUNCTION__, ##log_arg); \
}while (0)
#define Print_TRACE(log_fmt,log_arg...) \
do{ \
printf("L(%d)[%s:%d][%s] \n"log_fmt"\n", LL_TRACE,__FILE__, __LINE__, __FUNCTION__, ##log_arg); \
}while (0)
#define Print_DEBUG(log_fmt,log_arg...) \
do{ \
printf("L(%d)[%s:%d][%s] \n"log_fmt"\n", LL_DEBUG, __FILE__, __LINE__, __FUNCTION__, ##log_arg); \
}while (0)
#define Print_FATAL(log_fmt,log_arg...) \
do{ \
printf("L(%d)[%s:%d][%s] \n"log_fmt"\n",LL_FATAL, __FILE__, __LINE__, __FUNCTION__, ##log_arg); \
}while (0)
#endif
在尋求替代方案是發現c99版本後追加了"__VA_ARGS__"特殊形參表示可變參數的宏,即該宏可以替換省略號所代表的字符集,由於vs2015是支持c99的,因此稍微調整一下源碼即可實現跨平臺(win/linux)使用。而宏前面加上##(合併操作符)的作用在於,當可變參數的個數爲0時,這裏的##起到把前面多餘的","去掉的作用。源碼調整如下:
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#ifndef _PFUNC_PRINT_H_
#define _PFUNC_PRINT_H_
/***********************************************************************
*Copyright 2020-05-06, pyfree
*
*File Name : pfunc_print.h
*File Mark :
*Summary : 打印輸出通用宏定義
*
*Current Version : 1.01
*Author : pyfree
*FinishDate :
*
*Replace Version :
*Author :
*FinishDate :
************************************************************************/
typedef enum PrintLevel
{
LL_NOTICE = 1, //一般輸出
LL_WARNING = 2, //告警輸出
LL_TRACE = 3, //追蹤調試
LL_DEBUG = 4, //軟件bug
LL_FATAL = 5 //致命錯誤
}PrintLevel;
#define Print_NOTICE(log_fmt,...) \
do{ \
printf("L(%d)[%s:%d][%s] \n"log_fmt"\n", LL_NOTICE,__FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
}while (0)
#define Print_WARN(log_fmt,...) \
do{ \
printf("L(%d)[%s:%d][%s] \n"log_fmt"\n", LL_WARNING, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
}while (0)
#define Print_TRACE(log_fmt,...) \
do{ \
printf("L(%d)[%s:%d][%s] \n"log_fmt"\n", LL_TRACE,__FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
}while (0)
#define Print_DEBUG(log_fmt,...) \
do{ \
printf("L(%d)[%s:%d][%s] \n"log_fmt"\n", LL_DEBUG, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
}while (0)
#define Print_FATAL(log_fmt,...) \
do{ \
printf("L(%d)[%s:%d][%s] \n"log_fmt"\n",LL_FATAL, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
}while (0)
#endif