[C]C语言日志系统宏技巧解析
代码解释:日志标签字符串化宏
这段代码定义了一个名为 _LOG_TAG
的宏,用于将 LOG_TAG_CONST
转换为字符串形式。这在日志系统中很常见,用于为不同模块添加标识前缀。
宏结构分析
#define _LOG_TAG STR(LOG_TAG_CONST)
这个宏包含两个关键部分:
-
STR
宏:- 这是一个用于将参数转换为字符串的宏
- 通常定义为:
#define STR(x) #x
,其中#
是C语言的字符串化操作符 - 例如,
STR(FOO)
会被展开为"FOO"
-
LOG_TAG_CONST
:- 这是一个需要用户定义的常量,代表模块名或标签
- 例如,在某个文件中可能会定义:
#define LOG_TAG_CONST "SENSOR"
宏展开示例
假设 LOG_TAG_CONST
被定义为 "SENSOR"
,并且 STR
宏的实现为:
#define STR(x) #x
那么:
_LOG_TAG
会被展开为:
"SENSOR"
这个字符串通常会作为日志前缀,例如在之前的 log_info
宏中:
log_info("温度读数: %d", temp);
最终会生成类似这样的日志输出:
[Info]: SENSOR温度读数: 25
多级字符串化技巧
在某些情况下,你可能需要对已经是宏的参数进行字符串化。例如:
#define MODULE_NAME SENSOR
#define LOG_TAG_CONST MODULE_NAME
此时直接使用 STR(LOG_TAG_CONST)
会得到 "MODULE_NAME"
,而不是 "SENSOR"
。为了解决这个问题,通常需要使用两级字符串化:
#define STR(x) #x
#define XSTR(x) STR(x) // 二级字符串化宏#define _LOG_TAG XSTR(LOG_TAG_CONST)
这样,当 LOG_TAG_CONST
是另一个宏时,也能正确展开为对应的字符串。
使用建议
-
在每个源文件中定义
LOG_TAG_CONST
:// sensor.c #define LOG_TAG_CONST "SENSOR"
-
确保
STR
宏在使用_LOG_TAG
之前被定义:#define STR(x) #x #define _LOG_TAG STR(LOG_TAG_CONST)
-
如果需要多级展开,使用
XSTR
宏:#define STR(x) #x #define XSTR(x) STR(x) #define _LOG_TAG XSTR(LOG_TAG_CONST)
这种设计使得日志系统更加模块化,不同的源文件可以使用不同的标签,便于调试和维护。