c++编译链接过程

来源:互联网 发布:称重收银软件 编辑:程序博客网 时间:2024/06/06 11:11

Llinux下编译一个c++程序的典型过程:

1. 编译预处理  预编译程序完成的工作,可以说成是对源程序的“替换”工作。经过这个过程,生成一个没有宏定义、没有条件编译指令、没有特殊符号的输出文件。

  • 宏定义命令;例如#define
  • 条件编译指令;例如#ifdef
  • 头文件包含指令;例如#include
  • 特殊符号;例如__LINE__,__FILE__
  • 预处理模块;例如#pragma
2. 编译、优化阶段:通过词法分析、语法分析,在确认所有的指令都符合语法规则之后,将其翻译成等价的中间代码或汇编代码。在C++中,以下函数如果你没有定义但是被需要时,编译器会产生他们:默认构造函数、拷贝构造函数、析构函数、赋值运算符和一对取址运算符.

3. 汇编过程: 把汇编语言代码翻译成目标机器指令的过程。对于被翻译系统处理的每一个C语言源程序,都将最终经过这一处理而得到相应的目标文件。目标文件中所存放的也就是与源程序等效的目标的机器语言代码。

4.将有关的目标文件彼此相连接,也即将在一个文件中引用的符号同该符号在另外一个文件中的定义连接起来,使得所有的这些目标文件成为一个能够诶操作系统装入执行的统一整体。C++使用链接器以确保用到的函数都只被定义一次,以及确保static objects只被定义一次,会将我们做了声明但却未曾定义的函数检测出来。
链接有静态链接和动态链接。

  • 静态链接:在这种链接方式下,函数的代码将从其所在地静态链接库中被拷贝到最终的可执行程序中。这样该程序在被执行时这些代码将被装入到该进程的虚拟地址空间中。静态链接库实际上是一个目标文件的集合,其中的每个文件含有库中的一个或者一组相关函数的代码。     
  • 动态链接:在此种方式下,函数的代码被放到称作是动态链接库或共享对象的某个目标文件中。链接程序此时所作的只是在最终的可执行程序中记录下共享对象的名字以及其它少量的登记信息。在此可执行文件被执行时,动态链接库的全部内容将被映射到运行时相应进程的虚地址空间。动态链接程序将根据可执行程序中记录的信息找到相应的函数代码
备注:c++不像其他现代编程语言一样,用import或者using来引入当前源文件用到的库,必须用#include来机械的将库的接口声明以文本替换的方式引入,再重新parse一遍,这样这编译效率奇低,编译器动辄要parse几万行的预处理源代码,主要是预处理引入了不必要的依赖,这是在与C兼容的条件下不得不做出的妥协。