C 预编译中的二次替换问题
C 预编译中的二次替换问题
今天在阅读linux看门狗驱动的时候,发现一段奇怪的代码:
static int tmr_atboot = CONFIG_S3C2410_WATCHDOG_ATBOOT;
MODULE_PARM_DESC(tmr_atboot,
"Watchdog is started at boot time if set to 1, default="
__MODULE_STRING(CONFIG_S3C2410_WATCHDOG_ATBOOT));
依次跟进去宏的具体定义:
#define __MODULE_STRING(x) __stringify(x)
#define __stringify_1(x...) #x
#define __stringify(x...) __stringify_1(x)
这里一共使用了三处宏,分别是:__MODULE_STRING(x)、__stringify_1(x...)、__stringify(x...)。似乎这里的宏非常冗余。
GNU CPP Manual中是这样指出来的:
Macro arguments are completely macro-expanded before they are substituted into a macro body, unless they are stringified or pasted with other tokens. After substitution, the entire macro body, including the substituted arguments, is scanned again for macros to be expanded. The result is that the arguments are scanned twice to expand macro calls in them.
上面的总体意思就是:二次替换的问题。
具体使用例子来说明:
Main1.c
#include <stdio.h>
#define BUF_SIZE abc
#define __stringify(x) #x
Int main()
{
Printf(“%s\n”, __stringify(BUF_SIZE));
Return 0;
}
结果为: BUF_SIZE
Main2.c
#include <stdio.h>
#define BUF_SIZE abc
#define __stringify(x) __stringify_1(x)
#define __stringify_1(x) #x
Int main()
{
Printf(“%s\n”, __stringify(BUF_SIZE));
Return 0;
}
结果为: abc
总结,在宏替换时,如果出现标识字符串或者字符串连接的情况出现(“#”、“##”),那么宏替换会被截断,这个时候我们可以通过双层宏来完成深入替代的任务。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库