目录
一、C/C++编译过程
C/C++程序从源代码到可执行文件需要经理预处理(预编译),编译,汇编,链接四个过程:
1、预处理:对源代码中的伪指令(以# 开头的指令)和特殊符号进行处理,如#include指令,预处理会将对应的头文件(即.h文件,声明全局变量和函数,相当于java中的接口类)写入到源代码文件(即.c文件,包含函数的具体实现)。预处理后生成的是.i后缀结尾的文件,依然是文本文件。
2、编译:对预处理结果文件做词法和语法分析,在确认所有的指令都符合语法规则之后,将其翻译成等价的中间代码表示或汇编代码,翻译过程中会执行两种通用的编译优化,一种是代码层面的如代码外提,复制传播等,一种是跟硬件强相关的优化,包括选择更高效的机器指令,合理分配和指派寄存器,具体优化内容可参考《编译原理》,可通过gcc的参数指定优化的强度,通常优化强度越高编译越慢。因为寄存器的种类和数量是取决于CPU架构的,通常只有对应架构下的汇编指令可以直接操作寄存器,C语言中有register关键字请求编译器尽量将某个变量放入寄存器中,但是最终是否放入寄存器由编译器根据硬件环境决定。编译过程产生的文件还是文本文件,以.s结尾,该文件是对应平台下的翻译出的汇编代码。
3、汇编:指把汇编语言代码翻译成目标机器指令的过程,该过程相对简单,将对应的汇编指令替换成数字形式的指令码即可。汇编完成后生成的文件以.o结尾,通常是可重定位目标文件。
4、链接: 编译时是以单个.c文件为单位编译的,所以会产生多个.o文件,将多个.o文件与之依赖的共享库如libc链接在一起形成可执行文件,可执行文件的后缀可以是out或者elf。Linux加载可执行文件过程中不会校验文件后缀而校验是否符合ELF文件格式。
上述每一步操作都可以通过gcc命令单独触发,整体的过程如下图:
参考: C语言编译过程详解