nju-pa摸鱼记1-宏的妙用
一、前言
上学期在课内学习了《计算机体系结构》,一直对最后一章老师讲到的硬件模拟器念念不忘,好奇它的工作原理。好巧不巧,某日在我刷github的时候南京大学的ics-pa项目出现在了我的首页推荐中,于是我便打算利用寒假的时间过一下这个项目,并通过B站的专栏(现在同步到我的个人博客上)记录一些新的知识或者是心得体会。
二、使用宏配置编译选项
在项目代码进行编译前,需要先使用
1 |
|
对项目进行配置,在勾选了一些选项退出后,menuconfig
会根据之前的选项生成一些宏保存到若干文件中,供之后的.c文件或Makefile文件所包含(使用include)。这样,在C语言源文件或makefile脚本中通过对这些宏加以判断,就可以在编译时使用或抛弃某些特定的功能。
三、C语言中检测宏是否被定义
1、使用条件编译指令
在C语言源文件中,可以使用条件编译指令
1 |
|
将宏FOO
对应功能的代码包围起来,如果在menuconfig
中勾选了该宏所对应的选项,则宏FOO
会被定义,最终这段代码也会被编译。
2、使用宏定义
除了使用条件编译指令,代码框架还提供了另一种方式检测某个宏是否被定义。之所以要使用另一种方式,是因为条件编译指令不能使用在宏定义中,而频繁地使用条件编译指令会使代码的可读性大打折扣。实现这个功能的关键代码包括:
1 |
|
其中宏str(x)
使用#
运算符将x
转化为一个字符串。下面举一个例子来说明isdef
这个宏是怎么工作的:
1 |
|
经过预处理
1 |
|
main.i中的内容为:
1 |
|
可以发现,strcmp
函数的第一个参数对应isdef
宏定义中的"" #macro
,它直接将宏参数的名称转换为了字符串,而第二个参数对应"" str(macro)
,它先将FOO
替换为123
,然后将123
转换为字符串。因此当这两个参数不同时,说明宏已经被定义过。
通过上面的分析可以发现,宏isdef
不能检测宏定义的值与宏定义名称相同的宏,比如说
1 |
|
宏FOO
在预处理时仍然被替换为FOO
,最后将导致错误的结果。
四、参考资料
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!