C语言对log文件的处理,C语言 打log时,如何妥善的处理... 和 __VA_ARGS__

场景

当前遇到一个问题,有一个定义log输出的头文件,内容大致是这样的

#ifndef SWACK_COMMON_INCLUDE_SWACK_LOG_H_

#define SWACK_COMMON_INCLUDE_SWACK_LOG_H_

#define SWACK_LOG_LEVEL_DEBUG (1)

#define SWACK_LOG_LEVEL_ERROR (2)

#define SWACK_LOG_LEVEL_NONE (3)

#ifndef SWACK_LOG_LEVEL

#define SWACK_LOG_LEVEL SWACK_LOG_LEVEL_DEBUG

#endif

/* gcc on Linux */

#elif defined(__linux__)

#include

#include

#define MAX_LOG_SIZE 1024

#if (SWACK_LOG_LEVEL > SWACK_LOG_LEVEL_DEBUG)

#define LOGD(...)

#else

#define LOGD(...) \

{ \

printf(__VA_ARGS__); \

}

#endif

#if (SWACK_LOG_LEVEL > SWACK_LOG_LEVEL_ERROR)

#define LOGE(...)

#else

#define LOGE(...) { \

printf("LOGE (%s:%i) ",__func__,__LINE__); \

printf(__VA_ARGS__); \

}

#endif

/* TODO: Add LOGD/LOGE for other platforms */

#endif

#endif // SWACK_COMMON_INCLUDE_SWACK_LOG_H_

但是这里遇到一个问题:

如果我们定义了某个函数用于dump信息

void dump(void)

{

LOGD("111")

LOGD("222")

LOGD("333")

}

如果现在你把SWACK_LOG_LEVEL设置为3,此时不打印任何log

如果现在你把``你的项目对于代码编译有要求

add_compile_options(-g -fPIC -Wall -Wextra -Werror -pedantic -O3)

你会拿到一个错误:

error: unused parameter ‘buffer’ [-Werror=unused-parameter]

这个问题很显然,因为你现在不打印log了,那么dump函数为空的,它的哪些传输的变量啥也没做,所以会触发[-Werror=unused-parameter]

解决

出现错误的原因是,注销LOGD后,部分变量变成unused,所以我们需要把哪些参数used

解法一

一个最简单的方式,我们可以用sprintf

#define MAX_LOG_SIZE 1024

#define LOGD(...) \

{ \

char tmp_log[MAX_LOG_SIZE]; \

sprintf(tmp_log, __VA_ARGS__); \

}

解法二

这里很显然,只要用一下LOGD(...)后面的...,就能解决这个问题,所以以上源代码给出的方案是用sprintf来解决以上问题,但是这个解决方案显然很突兀,而且sprintf是会带来开销的

如果能把...直接void,那就太好了

在宏定义中,LOGD(...)传入的...,其实等效的等于__VA_ARGS__

所以可以类似方法解决

#define get1th_delay(a1, ...) a1

#define get2th_delay(a1, a2, ...) a2

#define get3th_delay(a1, a2, a3, ...) a3

#define get4th_delay(a1, a2, a3, a4, ...) a4

#define get5th_delay(a1, a2, a3, a4, a5, ...) a5

#define get6th_delay(a1, a2, a3, a4, a5, a6, ...) a6

#define get7th_delay(a1, a2, a3, a4, a5, a6, a7, ...) a7

#define get8th_delay(a1, a2, a3, a4, a5, a6, a7, a8, ...) a8

#define get9th_delay(a1, a2, a3, a4, a5, a6, a7, a8, a9, ...) a9

#define get10th_delay(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, ...) a10

#define leftBracket (

#define eatComma(...) , ##__VA_ARGS__

#define get1th(...) get1th_delay(__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1)

#define get2th(...) get2th_delay(__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1)

#define get3th(...) get3th_delay(__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1)

#define get4th(...) get4th_delay(__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1)

#define get5th(...) get5th_delay(__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1)

#define get6th(...) get6th_delay(__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1)

#define get7th(...) get7th_delay(__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1)

#define get8th(...) get8th_delay(__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1)

#define get9th(...) get9th_delay(__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1)

//#define parameterNum(...) get9th_delay leftBracket eatComma(__VA_ARGS__), 8,

// 7, 6, 5, 4, 3, 2, 1)

#define parameterNum(...) \

get10th_delay(__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)

#define LOGD(...) \

{ \

switch (parameterNum(__VA_ARGS__)) \

{ \

case 1: \

(void)(get1th(__VA_ARGS__)); \

break; \

case 2: \

(void)(get1th(__VA_ARGS__)); \

(void)(get2th(__VA_ARGS__)); \

break; \

case 3: \

(void)(get1th(__VA_ARGS__)); \

(void)(get2th(__VA_ARGS__)); \

(void)(get3th(__VA_ARGS__)); \

break; \

case 4: \

(void)(get1th(__VA_ARGS__)); \

(void)(get2th(__VA_ARGS__)); \

(void)(get3th(__VA_ARGS__)); \

(void)(get4th(__VA_ARGS__)); \

break; \

case 5: \

(void)(get1th(__VA_ARGS__)); \

(void)(get2th(__VA_ARGS__)); \

(void)(get3th(__VA_ARGS__)); \

(void)(get4th(__VA_ARGS__)); \

(void)(get5th(__VA_ARGS__)); \

break; \

} \

}

解法三

换一个思路,可以借助stdarg.h

首先了解下stdarg.h,主要包含以下宏定义

#define _INTSIZEOF(n) ((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) )

#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )

#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )

#define va_end(ap) ( ap = (va_list)0 )

然后我们利用他的特性

#ifdef __cplusplus

extern "C" {

#endif

static inline void void_log(char* fmt, ...)

{

(void)fmt;

va_list args;

va_start(args, fmt);

va_end(args);

}

#ifdef __cplusplus

}

#endif

#define LOGD(...) void_log(__VA_ARGS__)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值