本文主要总结,C++ 的编译链接以及底层相关概念。
1、编译过程
实际上,C++代码从预处理到执行经历了四个阶段:1)预处理 2)编译 3) 汇编 4) 链接
链接
预处理基本上是宏展开,替换,删除注释,头文件展开的过程。编译-汇编(gcc -c) 主要是将源文件编译成目标文件.o 的过程此时是汇编代码。
-
这里主要说明链接过程:
链接器将编译产生的.o 文件链接到一起,产生最后的可执行二进制文件。
人们把源代码的各个模块独立编译,然后按照需要将他们组装起来,这个组装的过程就是Linking
。 -
链接的过程主要为:
地址和空间分配、地址绑定、重定位 -
举例
例如在main函数种,使用了模块func.c 中的函数foo(), 因此在main函数的每一个调用foo的地方,都必须给出foo函数的地址。
但是,编译过程是独立的,因此main不知道foo的函数地址。因此需要将这些调用foo的目标地址搁置。等到链接阶段再将地址修正。
需要注意的是,func.c 每次被重新编译,foo函数的地址都可能产生变化。
连接器实际上会根据main函数调用foo,自动的去各个模块种寻找引用的符号foo,然后将main.c 模块种所有引用到foo的指令重新修正。
上述过程就是静态链接的基本过程。
详细过程
- 1 编译过程如下:
- Pre-processing: 通过GNU C 预处理器 cpp,这个可以打开头文件以及进行宏展开
cpp hello.c > hello.i
- Compilation : 对上述hello.i 进行汇编
gcc -S hello.i