gcc源码分析与应用教程(4)宏和预处理

本章继续介绍gcc词法分析,将重点介绍其中的宏定义与展开。
按照惯例,我们首先从源码中找到宏相关的内容,包括宏的关键字,以及c语义内置的宏。
我们在init.c文件中,找到gcc中内置的几种宏定义,来看下面的截图:
gcc源码分析与应用教程(4)宏和预处理
gcc源码分析与应用教程(4)宏和预处理
这些内置宏,具体的功能,我们这里就不去过多的介绍,感兴趣的可以去专门的网站上查询。
下一步,我们找到定义宏的关键字,在文件directives.c中,路径参照上一章截图:
gcc源码分析与应用教程(4)宏和预处理
第三步,是预处理过程中,宏的具体动作实现,也在directives.c,这里截取一部分:

gcc源码分析与应用教程(4)宏和预处理
相关的动作,被装入了一个叫dtable的指针函数数组里面:
gcc源码分析与应用教程(4)宏和预处理
gcc源码分析与应用教程(4)宏和预处理
这里宏的用法跟第二章类似,通过一种巧妙的方法,实现了多态。
不幸的是,gcc的源码比较凌乱,模块与模块之间的界限并不明显,再加上本人写作水平实在不怎么样,造成写文章比较困难,这个是后话。
现在先来梳理一下流程:
1.词法分析器,获取一个单词(lex.c文件,_cpp_lex_token函数)
2.判断字符,如果是#开头,则调用_cpp_handle_directive(directives.c文件)
3._cpp_handle_directive函数中,执行预处理动作,这里的cpp_hash是#的标记,可以回头看上一篇文章的截图。

gcc源码分析与应用教程(4)宏和预处理
接下来,读取下一个字符,这是一个递归的过程:
gcc源码分析与应用教程(4)宏和预处理
4.如果读取的下一个字符,根据返回的标识符,找到相应动作
gcc源码分析与应用教程(4)宏和预处理5.判断是否为关键字,如果是预处理关键字,则执行,不是预处理关键字,会查出空表。

gcc源码分析与应用教程(4)宏和预处理
6.返回到上一层,它的最上层是被cpp_get_token_1函数调用,这个函数在macro.c里面,在这里,会根据宏的定义,依次展开并替换成对于的字符。
gcc源码分析与应用教程(4)宏和预处理
这里的宏展开,是一个比较复杂的过程,本篇文章就到此为止,如果有人想了解更多细节,欢迎在评论区留言,我会专门写一篇详细的。
另外,本人发现自己的写作能力实在差劲,想找这方面有经验的人学习,请各位大神赐教,谢谢。