以前由于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