c++ 程序编译过程
总的来说分成四个阶段:预处理 编译 汇编 链接
预处理
- 预处理器(cpp)将所有的#define删除,并且展开所有的宏定义(例如#define PI 3.14 这句在预处理阶段,后期的所有PI都会被替换成3.14)。
- 处理所有的条件预编译指令,比如#if、#ifdef、#elif、#else、#endif等。
- 处理#include预编译指令,将被包含的文件直接插入到预编译指令的位置。
- 删除所有的注释。
- 添加行号和文件标识,以便编译时产生调试用的行号及编译错误警告行号。
- 保留所有的#pragma编译器指令,因为编译器需要使用它们。
- 使用
gcc -E hello.c -o hello.i
命令来进行预处理, 预处理得到的另一个程序通常是以.i作为文件扩展名。
读取源代码并对其中的以#开头的指令和特殊符号进行处理。包括宏定义,条件编译,头文件,特殊符号。将.cpp 转化成 .i
编译优化
首先 通过词法分析和语法分析,确认所有的指令都符合语法规则。其次将其翻译成等价的中间代码表示或汇编代码。template和inline函数在此阶段处理。优化一部分是对中间代码的优化。这种优化不依赖于具体的计算机。另一种优化则主要针对目标代码的生成而进行的,和硬件有关。将 .i 转化成.s
全局变量,静态全局变量,类的静态数据成员,都在编译时分配内存空间,完成初始化。
而静态局部变量则是在第一次使用到的时候分配内存并且初始化。
汇编
将汇编代码转换成二进制机器码
通常一个目标文件中至少有两个段,代码段和数据段. 将 .s 转化成.o
链接
链接程序的主要工作就是将有关的目标文件彼此相连接,使得所有的这些目标文件成为一个能够被操作系统装入执行的统一整体。主要分动态链接(.so)和静态链接(.a) .将 .o 转化成.out
后缀名 | 描述 |
---|---|
.c/.C/.cc/.cp/.cpp/.cxx/.c++ | 源代码文件,函数和变量的定义/实现 |
.h | 头文件,函数和变量的声明 |
.ii | 编译预处理产生的文件 |
.s | 编译产生的汇编语言文件 |
.o (.obj in Windows) | 编译产生的中间目标文件 |
.a | 打包目标文件的库文件 |
.so | 编译产生的动态库文件 |
.out (.exe in Windows) | 链接目标文件产生的可执行文件 |
VC++6.0中Compile和Build的区别
“compile”是“编译”的意思,“build”是“链接”的意思。
compile 的作用是对你的代码进行语法检查,将你的文本程序语言转化成计算机可以运行的“01010….”形式的二进制文件。
build 的作用是将你在程序中调用到的类库融合到你的程序中,比如你用到了printf()函数,那么内部实现该函数的类库代码就会添加到你的程序中。
compile过程生成“.obj”文件或”.o”文件,这个和编译器有关,vc++中是“.obj”文件。
build过程生成“.exe”文件。这个可以直接运行
理论上来说应该先点”complile”,再点”build”。不过在vc++中直接点“build”它会自动先给你compile再build
参考
https://blog.csdn.net/u011718663/article/details/118163962
https://blog.csdn.net/hexkang/article/details/126402730