预处理阶段
预处理阶段处理所有以#开头的指令,包括宏定义、条件编译和头文件包含。该阶段生成.i文件,仍是文本格式但已完成宏展开。
头文件内容会被直接插入源文件位置,注释会被完全删除。条件编译指令会根据宏定义决定代码块是否保留。
编译阶段
编译器将预处理后的代码转换为汇编语言,生成.s文件。该过程包含词法分析、语法检查、语义分析和代码优化。
现代编译器会进行常量折叠、死代码消除等优化。例如int a=1+2可能被优化为int a=3。
汇编阶段
汇编器将汇编代码转换为机器码,生成.o目标文件。此时代码已是二进制格式,但函数地址和外部引用尚未解析。
目标文件包含代码段、数据段和符号表等信息,为链接阶段做准备。
链接阶段
链接器合并多个目标文件并解析符号引用,主要完成两项工作:
- 符号解析:查找函数和变量的实际定义地址
- 重定位:调整代码中的相对地址引用
静态链接会将库代码直接嵌入可执行文件,动态链接则在运行时加载共享库。
常用编译命令
查看预处理结果:
bash
g++ -E main.cpp -o main.i
生成汇编代码:
bash
g++ -S main.cpp
生成目标文件:
bash
g++ -c main.cpp
完整编译流程:
bash
g++ main.cpp -o app
理解编译流程有助于解决符号冲突、链接错误等问题,是进行性能优化和底层开发的基础。