程序员的自我修养读书笔记
1.编译和链接
像VS,Delphi这种集成开发环境(IDE),他们一般把编译和链接的过程一步完成,将这种编译和链接合并到一起的过程叫做构建,构建的英文名是Build,所以你可以看到VS的编译就是这个词
2.中间的过程
比如一个hello world的小程序,编译过程也是很复杂的,可以分为4步:预处理,编译,汇编,链接
2.1预处理
对C语言来说,比如源文件是.c,那他就会把.c以及相关的头文件,全部被预编译器cpp预编译到一个文件里,这个文件是.i文件
源文件是.cpp,那就是到.ii文件
这两个文件其实就是预处理后的文件
预编译过程主要是解决了“#”开始的预编译指令,比如#include, #define这些
- 把#include全部递归展开,把#define这些宏展开,并且删除#define
- 处理所有的条件编译指令,比如”#if”, “#ifdef”, “#elif”, “#else”, “#endif”
- 删除所有的注释 // 和 /**/
- 添加行号和文件名标识,比如#2 “hello.c” 2,便于调试用,或者编译错误时显示行号
- 保留所有的#pragma编译器指令,因为编译器需要使用他们
经过这些处理后的.i文件不包含宏定义,因为已经被展开了,并且包含的文件也已经被插入到.i文件里
2.2编译
就是把预处理完的文件,经过一系列词法分析,语法分析,语义分析以及优化后生成的相应的汇编代码文件,所以本质上生成的是汇编代码,现代gcc把预编译和编译两个步骤合并为一个,使用一个叫cc1的程序完成这两个步骤,执行完后,会生成汇编文件,hello.s文件
对C语言的话,是cc1
C++是cc1plus
Objective-C是cc1obj
fortran是f771
Java是jc1
实际上gcc这个命令只是这些后台程序的包装,它会根据不同的参数要求去调用预编译编译程序cc1,汇编器as,链接器Id
2.3汇编
汇编器是把汇编语言转为机器可以执行的指令,每条汇编语句都对应一个机器指令,所以汇编器的汇编过程相对于编译器来说很简单,没有复杂的语法,也没有语义,也不用指令优化
这个汇编后形成的文件叫做目标文件,是hello.o
2.4链接
为什么不汇编器直接形成可执行文件,而是形成目标文件呢,为什么要链接呢
其实我们需要把一大堆文件也就是.o文件链接起来才可以得到.out文件,就是最终的可执行文件
链接到底起个什么作用呢?