前言
一般我们在写代码的时候,写完直接点击编译运行,但是却并未思考,编译这个过程到底发生了什么;实际上,当前的很多IDE(如Visual Studio)都将这个过程忽略了; 也就是从源文件(.cpp)到可执行文件(.exe)中间的过程我们并未过多了解。
.cpp文件到可执行文件.exe中间的过程如下图所示(预编译(Propressing)–>编译(Compliation)–>汇编(Assembly)–>链接(Linking))4个步骤,执行这四个阶段的程序(预处理器、编译器、汇编器、和链接器)一起构成了编译系统。
1 预编译(Preprocessing)
主要是处理源代码文件中的预编译指令,例如#xxxx,从.cpp文件变成.i文件
- 预编译指令的展开 所谓展开就是复制 #include的内容
- 添加行号和文件名等调试信息
- 删除注释
- 处理编译器指令
序号 | 预处理名称 | 意义 |
---|---|---|
01 | #define | 宏定义 |
02 | #undef | 撤销已定义过的宏名 |
03 | #include | 使编译程序将另一源文件嵌入到带有#include的源文件中 |
04 | #if | #if 的一般含义是如果#if 后面的常量表达式为true, 则编译它与#endif 之间的代码,否则跳过这些代码。命令#endif 标识一个#if 块的结束。#else命令的功能有点像C 语言中的else, #else 建立另一种选择(在#if 失败的情况下)。#elif 命令意义与 else if相同,它形成一个if else-if 阶梯状语句,可进行多种编译选择 |
05 | #else | |
06 | #elif | |
07 | #endif | |
08 | #ifdef | 用#ifdef 与#ifndef命令分别表示“如果有定义”及“如果无定义”,是条件编译的另一种方法 |
09 | #ifndef | |
10 | #line | 改变当前行数和文件名称,它们是在编译程序中预先定义的标识符,命令基本形式为:#line number["filename"] |
11 | #error | 编译程序时,只要遇到#error就会生成一个编译错误提示消息,并停止编译 |
12 | #pragma | 为实现时定义的命令,它允许向编译程序传送各种指令,编译程序可能有一种选择,它支持对程序执行的跟踪。可用#pragma语句指定一个跟踪选择。 |
还有下列几种预处理宏(是双下划线)
__LINE__表示正在编译的文件的行号
__FILE__表示正在编译的文件的名字
__DATE__表示编译时刻的日期字符串,例如: “25 Dec 2007”
__TIME__表示编译时刻的时间字符串,例如: “12:30:55”
__STDC__判断该文件是不是定义成标准 C 程序
2 编译(Compliation)
编译主要负责识别源代码,并将其转换成优化后的汇编代码,从.i文件变成.s文件(汇编代码文件)
主要工作是对.i文件进行一系列的词法分析等,目的是让编译器知道这写的代码是啥
- 词法分析: 主要是将源代码指令识别分解成一个个符号、关键字、数字等
- 语法分析: 主要是分析表达式是否合理,例如不允许指针和指针相乘运算等
- 语义分析: 在编译阶段主要是静态语义;工作是声明和类型的匹配、类型的转换,经过语义分析之后,所有的表达式都被标注了相对应的类型
- 中间语言生成: 将上述的源代码转换成适合用于转换为汇编代码的中间代码;我的理解是将这些代码变得更加简洁(这其中也必然存在拆分动作)
- 目标代码生成和优化: a) 所谓的目标代码,其实是优化后的汇编代码; b) 将中间代码转化成汇编代码; c) 再将汇编代码进行优化; d) 最后成为.s文件
4 汇编(Assembly)
汇编是一个理解起来比较简单的过程:对应不同的机器的指令集,将汇编代码一条一条翻译为机器指令
将.s文件变成.o文件(也即目标文件)
汇编器将上一步骤优化后的汇编代码一条一条的转化为机器指令
机器指令(形如:010101111000110101…)是唯一可以被计算机读懂的指令
5 链接(Linking)
链接主要负责将目标文件(.o文件)和库文件整合起来,就像拼图一样
将.o文件和运行时库(Runtime Library)中的目标文件组装成可执行的.exe文件
这个过程就像是拼图一样,将相互需要的文件进行组装(比如a.o文件中调用了b.o文件中的函数等)
备注:什么是运行时库(Runtime Library)?
库其实是支持程序运行的基本函数的集合
是一组目标文件的包,就是一些常用的代码编译成目标文件后打包存放就是所谓的库
参考
https://blog.csdn.net/qq_41523096/article/details/121092139