c++基础之编译过程

从C++文件到可执行文件经过了哪几个过程

​ 预编译、编译、汇编、链接

1.预编译

​ 处理#开头的指令,比如拷贝#include包含的文件代码,#define宏定义的替换,条件编译等

   就是为编译做的预备工作的阶段

   主要处理#开始的预编译指令

   预编译指令指示了在程序正式编译前就由编译器进行的操作,可以放在程序中的任何位置。

2.编译

​ 编译器对预编译后的c++文件进行词法分析、语法分析、语义分析和优化,翻译成文本文件xxx.s,包含了一系列汇编语言

3.汇编

​ 汇编器将xxx.s翻译成机器语言指令,把这些指令打包成一种叫做可重定位目标程序的格式,并将结果保存在目标文件xxx.o中,xxx.o是一个二进制文件。

4.链接

​ 链接(linking)是将各种代码和数据片段收集并组合成为一个单一文件的过程,这个文件可被加载(复制)到内存并执行。链接可以执行于编译时(compile time),也就是在源代码被翻译成机器代码时;也可以执行于加载时(load time),也就是在程序被加载器(loader)加载到内存并执行时;甚至执行于运行时(run time),也就是由应用程序来执行。链接是由叫链接器(linker)的程序自动执行的。

链接的过程做了什么?

​ 1.符号解析:目标文件和库中包含很多符号(函数、变量名),它们在编译过程中被分配到了唯一的标识符。链接器需要解析这些符号,找到它们在其他文件中的定义。

​ 2.地址分配:链接器为每个目标文件和库分配内存地址空间,并确定它们在最终可执行文件中的布局。连接器还需要处理重定位,即根据实际内存地址更新代码中的地址引用。

​ 3.库依赖管理:连接器处理程序对库的依赖关系,确保所有需要的库都被包含在可执行文件中。链接器还需要处理库之间的依赖关系,确保它们按正确顺序链接。

链接存在的意义

​ 链接使得分离编译成为可能,我们不用将一个大型的应用程序组织成一个巨大的源文件,而是可以把它分解成为更小、更好管理的模块,可以独立的修改和编译这些模块。当我们改变这些模块中的一个时,只需要简单的重新编译它,并重新链接应用,而不必重新编译其他文件。