我们需要的文件结构如上
main.cpp
add.h
add.cpp
add.h
这里使用riscv的工具链编译为.i文件,需要使用-E,就是只进行预处理,我们可以得到两个.i文件即main.i和add.i
main.i
这里看到main.i里头文件全部替换,然后多了三万多行
所以这部分纯粹就是代码插入,也就是说
对于C++编译过程中预处理这一步来说,不区分头文件来源。不论是标准库的头文件,还是我们自己写的头文件,预处理器处理它们的方式是相同的。预处理主要做以下几件事:
-
宏定义展开:将所有的宏定义替换成相应的代码。
-
文件包含处理:处理
#include
指令,将包含的头文件内容插入到包含指令的位置。这里不区分标准库头文件和自定义头文件,预处理器根据指定的搜索路径查找头文件,并将头文件内容插入到源文件中。 -
条件编译指令处理:处理
#if
、#ifdef
、#ifndef
、#else
、#elif
、#endif
等条件编译指令。 -
移除注释:将代码中的注释移除。
-
添加行标识和文件标识:预处理器还会添加行号和文件名标识,这对于编译时的错误定位是非常有用的。
对于引入的头文件,预处理器的处理流程大致如下:
- 当遇到一个
#include
指令时,预处理器会查找指定的文件。 - 如果是使用尖括号
< >
包围的文件名,如#include <iostream>
,预处理器通常在系统的标准库路径中查找。 - 如果是使用双引号
" "
包围的文件名,如#include "myheader.h"
,预处理器首先在源文件的相同目录下查找,如果没有找到,再按照编译器配置的搜索路径查找,这通常包括系统的标准库路径。 - 找到头文件后,预处理器将头文件的全部内容插入到
#include
指令的位置,然后继续处理插入的内容。
简而言之,不论头文件的来源如何,预处理器的处理方式是一致的,都是将头文件内容插入到源文件中,然后继续进行宏展开、条件编译处理等操作。