NEMU中IFDEF宏的实现方法
NEMU中marco.h的宏实现十分神奇,这里以IFDEF宏的实现为例子,简单介绍一下.
本文章为一生一芯教学项目的个人理解,笔者并不能保证其正确,请注意学术诚信
笔者并非计算机科班,内容难免存在错误,如您发现,欢迎与我联系.
目的:实现#IFDEF(CONFIG_ITRACE, init_disasm())宏,若CONFIG_ITRACE宏被定义,则执行函数init_disasm(),否则不执行任何函数
1 |
|
#define ISDEF(macro) MUXDEF(macro, 1, 0)
#define MUXDEF(macro, X, Y) MUX_MACRO_PROPERTY(__P_DEF_, macro, X, Y)
#define MUX_MACRO_PROPERTY(p, macro, a, b) MUX_WITH_COMMA(concat(p, macro), a, b)
若MARCO_1被定义:MUXDEF(MACRO_1, 1, 0)
被展开为MUX_MACRO_PROPERTY(__P_DEF_, MACRO_1, 1, 0)
拼接连接符concat(__P_DEF_, MACRO_1) // 结果为 __P_DEF_0
#define __P_DEF_0 X, // 包含逗号
被展开为MUX_WITH_COMMA(__P_DEF_0, 1, 0)
被展开为CHOOSE2nd(X, , 1, 0) // 选择第二个参数:space
(逗号替换逻辑,这里‘X,’作为一个整体传进去,即X,就是一个参数,space之后的逗号是分割这个整体的,而’X,’内的逗号又会导致其被解析成两个参数。)
对于#define CONFIG_ITRACE // 假设 CONFIG_ITRACE 被定义
IFDEF(CONFIG_ITRACE, init_disasm());
调用#IFDEFMUXDEF(CONFIG_ITRACE, __KEEP, __IGNORE)(init_disasm());
展开MUXDEFMUX_MACRO_PROPERTY(__P_DEF_, CONFIG_ITRACE, __KEEP, __IGNORE)(init_disasm());
拼接连接符concat(__P_DEF_, CONFIG_ITRACE) -> __P_DEF_1
#define __P_DEF_1 X,
其结果MUX_WITH_COMMA(__P_DEF_1, __KEEP, __IGNORE)(init_disasm());
处理MUX_WITH_COMMACHOOSE2nd(__P_DEF_1 __KEEP, __IGNORE)(init_disasm());
__P_DEF_1 包含一个逗号,被展开为’ X,__KEEP, __IGNORE’,所以选择第二个参数 __KEEP:__KEEP(init_disasm());
调用__KEEPinit_disasm();
实现若CONFIG_ITRACE被定义,执行init_disasm();的效果。
而若CONFIG_ITRACE宏未定义:IFDEF(CONFIG_ITRACE, init_disasm());
调用#IFDEFMUXDEF(CONFIG_ITRACE, __KEEP, __IGNORE)(init_disasm());
拼接连接符,现在其未被定义concat(__P_DEF_, CONFIG_ITRACE) -> __P_DEF_ CONFIG_ITRACE
其结果MUX_WITH_COMMA(__P_DEF_ CONFIG_ITRACE, __KEEP, __IGNORE)(init_disasm());
处理MUX_WITH_COMMACHOOSE2nd(__P_DEF_ CONFIG_ITRACE __KEEP, __IGNORE)(init_disasm());
现在__P_DEF_ CONFIG_ITRACE __KEEP,未被定义(不像上个例子能被展开为‘X,’)
此时选择第二个参数__IGNORE__IGNORE(init_disasm())
展开为空。
实现若CONFIG_ITRACE未被定义,不执行任何函数的效果。