编译器linker工作原理

编译器linker工作原理

ID:9423619

大小:29.09 KB

页数:12页

时间:2018-04-30

编译器linker工作原理_第1页
编译器linker工作原理_第2页
编译器linker工作原理_第3页
编译器linker工作原理_第4页
编译器linker工作原理_第5页
资源描述:

《编译器linker工作原理》由会员上传分享,免费在线阅读,更多相关内容在应用文档-天天文库

1、编译器Linker工作原理收藏转自:http://hi.baidu.com/angelanpan/blog/item/f30cbc3e3ee10cfa838b13cd.htmlLNK2005“符号已定义”错误及Linker工作原理2006-10-2417:44许多VisualC++的使用者都碰到过LNK2005:symbolalreadydefined和LNK1169:oneormoremultiplydefinedsymbolsfound这样的链接错误,而且通常是在使用第三方库时遇到的。对于这个问题,有的朋友可能不知其然,而有的朋友可能知其然却不知其所以然,那么本文就

2、试图为大家彻底解开关于它的种种疑惑。      大家都知道,从C/C++源程序到可执行文件要经历两个阶段:(1)编译器将源文件编译成汇编代码,然后由汇编器(assembler)翻译成机器指令(再加上其它相关信息)后输出到一个个目标文件(objectfile,VC的编译器编译出的目标文件默认的后缀名是.obj)中;(2)链接器(linker)将一个个的目标文件(或许还会有若干程序库)链接在一起生成一个完整的可执行文件。   编译器编译源文件时会把源文件的全局符号(globalsymbol)分成强(strong)和弱(weak)两类传给汇编器,而随后汇编器则将强弱信息编码并

3、保存在目标文件的符号表中。那么何谓强弱呢?编译器认为函数与初始化了的全局变量都是强符号,而未初始化的全局变量则成了弱符号。比如有这么个源文件:externinterrorno;intbuf[2]={1,2};int*p;intmain(){  return0;}其中main、buf是强符号,p是弱符号,而errorno则非强非弱,因为它只是个外部变量的使用声明。   有了强弱符号的概念,我们就可以看看链接器是如何处理与选择被多次定义过的全局符号:规则1:不允许强符号被多次定义(即不同的目标文件中不能有同名的强符号);规则2:如果一个符号在某个目标文件中是强符号,在其它文

4、件中都是弱符号,那么选择强符号;规则3:如果一个符号在所有目标文件中都是弱符号,那么选择其中任意一个;由上可知多个目标文件不能重复定义同名的函数与初始化了的全局变量,否则必然导致LNK2005和LNK1169两种链接错误。可是,有的时候我们并没有在自己的程序中发现这样的重定义现象,却也遇到了此种链接错误,这又是何解?嗯,问题稍微有点儿复杂,容我慢慢道来。   众所周知,ANSIC/C++定义了相当多的标准函数,而它们又分布在许多不同的目标文件中,如果直接以目标文件的形式提供给程序员使用的话,就需要他们确切地知道哪个函数存在于哪个目标文件中,并且在链接时显式地指定目标文件

5、名才能成功地生成可执行文件,显然这是一个巨大的负担。所以C语言提供了一种将多个目标文件打包成一个文件的机制,这就是静态程序库(staticlibrary)。开发者在链接时只需指定程序库的文件名,链接器就会自动到程序库中寻找那些应用程序确实用到的目标模块,并把(且只把)它们从库中拷贝出来参与构建可执行文件。几乎所有的C/C++开发系统都会把标准函数打包成标准库提供给开发者使用(有不这么做的吗?)。   程序库为开发者带来了方便,但同时也是某些混乱的根源。我们来看看链接器是如何解析(resolve)对程序库的引用的。    在符号解析(symbolresolution)阶段

6、,链接器按照所有目标文件和库文件出现在命令行中的顺序从左至右依次扫描它们,在此期间它要维护若干个集合:(1)集合E是将被合并到一起组成可执行文件的所有目标文件集合;(2)集合U是未解析符号(unresolvedsymbols,比如已经被引用但是还未被定义的符号)的集合;(3)集合D是所有之前已被加入到E的目标文件定义的符号集合。一开始,E、U、D都是空的。(1):对命令行中的每一个输入文件f,链接器确定它是目标文件还是库文件,如果它是目标文件,就把f加入到E,并把f中未解析的符号和已定义的符号分别加入到U、D集合中,然后处理下一个输入文件。(2):如果f是一个库文件,链

7、接器会尝试把U中的所有未解析符号与f中各目标模块定义的符号进行匹配。如果某个目标模块m定义了一个U中的未解析符号,那么就把m加入到E中,并把m中未解析的符号和已定义的符号分别加入到U、D集合中。不断地对f中的所有目标模块重复这个过程直至到达一个不动点(fixedpoint),此时U和D不再变化。而那些未加入到E中的f里的目标模块就被简单地丢弃,链接器继续处理下一输入文件。(3):如果处理过程中往D加入一个已存在的符号,或者当扫描完所有输入文件时U非空,链接器报错并停止动作。否则,它把E中的所有目标文件合并在一起生成可执行文件。   VC带

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。