• c++编译链接过程


    大家都知道,从 C/C++ 源程序到可执行文件要经历两个阶段 :

    (1) 编译器将源文件编译成汇编代码,然后由汇编器 (assembler) 翻译成机器指令 ( 再加上其它相关信息 ) 后输出到一个个目标文件 (object file, VC 的编译器编译出的目标文件默认的后缀名是 .obj) 中;

    (2) 链接器 (linker) 将一个个的目标文件 ( 或许还会有若干程序库 ) 链接在一起生成一个完整的可执行文件。

    编译器编译源文件时会把源文件的全局符号 (global symbol) 分成强 (strong) 和弱 (weak) 两类传给汇编器,而随后汇编器则将强弱信息编码并保存在目标文件的符号表中。那么何谓强弱呢?

    extern int errorno;

    int buf[2] = {1,2};

    int *p;

    int main()
    {
    return 0;
    }

    其中 main 、 buf 是强符号, p 是弱符号,而 errorno 则非强非弱,因为它只是个外部变量的使用声明。

    有了强弱符号的概念,我们就可以看看链接器是如何处理与选择被多次定义过的全局符号 :

    规则 1: 不允许强符号被多次定义 ( 即不同的目标文件中不能有同名的强符号 ) ;

    规则 2: 如果一个符号在某个目标文件中是强符号,在其它文件中都是弱符号,那么选择强符号;

    规则 3: 如果一个符号在所有目标文件中都是弱符号,那么选择其中任意一个;

    多个目标文件不能重复定义同名的函数初始化了的全局变量,否则必然导致 LNK2005 和 LNK1169 两种链接错误。

    C 语言提供了一种将多个目标文件打包成一个文件的机制,这就是静态程序库 (static library) 。开发者在链接时只需指定程序库的文件名(如:XXX.lib),链接器就会自动到程序库中寻找那些应用程序确实用到的目标模块,并把 ( 且只把 ) 它们从库中拷贝出来参与构建可执行文件。几乎所有的 C/C++ 开发系统都会把标准函数打包成标准库提供给开发者使用.

    符号解析 (symbol resolution) 阶段,
    链接器按照所有目标文件(xxx.obj)库文件(xxx.lib)出现在命令行中的顺序从左至右依次扫描它们,在此期间它要维护若干个集合 :

    (1) 集合 E
    是将被合并到一起组成可执行文件的所有目标文件集合;

    (2) 集合 U
    是未解析符号 (unresolved symbols ,比如已经被引用但是还未被定义的符号 ) 的集合;

    (3) 集合 D
    是所有之前已被加入到 E 中已经定义的符号集合。一开始, E 、 U 、 D 都是空的。
    【如果处理过程中往 D 加入一个已存在的符号 ,或者当扫描完所有输入文件时 U 非空,链接器报错并停止动作。否则,它把 E 中的所有目标文件合并在一起生成可执行文件。 】

    VC 带的编译器名字叫 cl.exe ,它有这么几个与标准程序库有关的选项 : /ML 、 /MLd 、 /MT 、 /MTd 、 /MD 、 /MDd 。这些选项告诉编译器应用程序想使用什么版本的 C 标准程序库。
    /ML( 缺省选项 ) 对应单线程静态版的标准程序库 (libc.lib) ; /MT 对应多线程静态版标准库 (libcmt.lib) ,此时编译器会自动定义 _MT 宏;
    /MD 对应多线程 DLL 版 ( 导入库 msvcrt.lib , DLL 是 msvcrt.dll) ,编译器自动定义 _MT 和 _DLL 两个宏。
    后面加 d 的选项都会让编译器自动多定义一个 _DEBUG 宏,表示要使用对应标准库的调试版,因此
    /MLd 对应调试版单线程静态标准库 (libcd.lib) ,
    /MTd 对应调试版多线程静态标准库 (libcmtd.lib) ,
    /MDd 对应调试版多线程 DLL 标准库 ( 导入库 msvcrtd.lib , DLL 是 msvcrtd.dll) 。

  • 相关阅读:
    elasticsearch 6.x.x 获取客户端方法
    struts2+spring 配置404和500错误页面
    linux 部署redis集群 碰到的坑
    Linux下安装redis
    struts加载spring
    有关struts中DispatchAction的用法小结
    spring AOP原理
    struts2.0的工作原理?
    Spring MVC的实现原理
    spring 的单例模式
  • 原文地址:https://www.cnblogs.com/fag888/p/5789112.html
Copyright © 2020-2023  润新知