c语言链接器的作用,C语言link过程详解(多文件编译过程)

本文详细介绍了C/C++程序的链接过程,包括编译、目标文件、链接器的工作原理,以及如何处理未解决的外部链接和重复的外部符号。通过实例解释了编译单元、目标文件、符号表、地址重定向表的角色,以及extern、static等关键字的影响。此外,还讨论了头文件中声明和定义的注意事项,以及内联函数和类静态成员的链接属性。

一、详解link

有些人写C/C++(以下假定为C++)程序,对unresolved external link或者duplicated external simbol的错误信息不知所措(因为这样的错误信息不能定位到某一行)。或者对语言的一些部分不知道为什么要(或者不要)这样那样设计。了解本文之后,或许会有一些答案。

首先看看我们是如何写一个程序的。如果你在使用某种IDE(Visual Studio,Elicpse,Dev C++等),你可能不会发现程序是如何组织起来的(很多人因此而反对初学者使用IDE)。因为使用IDE,你所做的事情,就是在一个项目里新建一系列的.cpp和.h文件,编写好之后在菜单里点击“编译”,就万事大吉了。但其实以前,程序员写程序不是这样的。他们首先要打开一个编辑器,像编写文本文件一样的写好代码,然后在命令行下敲

cc 1.cpp -o 1.o

cc 2.cpp -o 2.o

cc 3.cpp -o 3.o

这里cc代表某个C/C++编译器,后面紧跟着要编译的cpp文件,并且以-o指定要输出的文件(请原谅我没有使用任何一个流行编译器作为例子)。这样当前目录下就会出现:

1.o 2.o 3.o

最后,程序员还要键入

link 1.o 2.o 3.o -o a.out

来生成最终的可执行文件a.out。现在的IDE,其实也同样遵照着这个步骤,只不过把一切都自动化了。让我们来分析上面的过程,看看能发现什么。

首先,对源代码进行编译,是对各个cpp文件单独进行的。对于每一次编译,如果排除在cpp文件里include别的cpp文件的情况(这是C++代码编写中极其错误的写法),那么编译器仅仅知道当前要编译的那一个cpp文件,对其他的cpp文件的存在完全不知情。

其次,每个cpp文件编译后,产生的.o文件,要被一个链接器(link)所读入,才能最终生成可执行文件。

二、C/C++程序是如何组织的

首先要知道一些概念:

编译:编译器对源代码进行编译,是将以文本形式存在的源代码翻译为机器语言形式的目标文件的过程。

编译单元:对于C++来说,每一个cpp文件就是一个编译单元。从之前的编译过程的演示可以看出,各个编译单元之间是互相不可知的。

目标文件:由编译所生成的文件,以机器码的形式包含了编译单元里所有的代码和数据,以及一些其他的信息。

下面我们具体看看编译的过程。我们跳过语法分析等,直接来到目标文件的生成。假设我们有一个1.cpp文件

int n = 1;

void f()

{

++n;

}

它编译出来的目标文件1.o

就会有一个区域(假定名称为2进制段),包含了以上数据/函数,其中有n, f,以文件偏移量的形式给出很可能就是:

偏移量 内容 长度

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值