编译和链接

1 篇文章 0 订阅
1 篇文章 0 订阅

编译和链接

  • 当程序员之间在讨论创建程序之时,他们经常会说,“编译好了”或者,当问起他们程序是是否工作时,“让我们编译看看”。这些术语或许就是新手程序员的困惑之源。编译并不意味着创建了一个可执行文件!相反,创建一个可执行的文件是一个多阶段的过程,分为两个部分:编译链接。在现实中,即使一个程序“编译成功”也不意味着它能实际运行,因为有可能在链接阶段发生了错误。从源代码到可执行文件的整个过程更应该被称作构建(Build)

编译

  • 编译指代处理源代码文件(.c,.cc,or .cpp)和创建“对象(object)”文件。这一步创建的文件是无法被用户直接运行的。相反,编译器仅仅产生对应于编译的源代码文件的机器语言指令。举个例子,如果你编译(但不链接)三个独立的文件,你会得到三个对象文件作为输出,每一个都有名称 filename.o或者filename.obj(扩展名取决于你所使用的编译器)。每一个文件都包含从源代码到机器码的转换–但你现在还不能运行他们!你需要把它们变成你操作系统可以运行的可执行文件。这就是链接器发挥作用的地方。

链接

  • 链接指代从多个对象文件到单个可执行文件的创建过程。在这一个步中,一般链接器都会对未定义的函数发出警告(通常来说,是main本身)。在编译过程中,如果编译器没能发现特定函数的定义,它(编译器)就会假定这个函数在其他文件中。如果情况不是这样,那么编译器也没办法知道(这个未定义的函数到底在哪)–因为编译器只能在同一时间浏览一个文件内的内容。但链接器却可以查看多个文件(对象文件)并尝试查找出未定义函数的引用。
  • 你或许会疑惑为什么将程序构建过程分为编译和链接两部分。答案是:首先,这样的方法更容易实现。编译器做它该做的事,链接器做它该做的事–保持功能间的独立,使程序的复杂度得以降低。另一方面(更明显)的优点就是,一个非常大的程序中一个文件改变了,不需要重新编译整个程序,只需要编译改变的那个文件就行了。相反,使用所谓的”条件编译”,只需要编译哪些已经改变的源文件;其余的,对象文件是链接器足够的输入。最后,这使得实现预编译代码的库文件变得简单:仅仅创建对象文件然后将它和其余的对象文件链接起来。(顺便说一句,每个文件的编译与其他文件中的信息无关的编译过程,被称为“单独编译模型”)。
  • 为了获得条件编译的全部好处,让程序来帮助你比试图记住自上次编译以来更改过的文件可能更容易。(当然,您可以重新编译每个文件的时间戳大于相应的目标文件的时间戳。)如果你在集成开发环境(IDE)下工作,IDE会帮你处理好这一切。如果你使用命令行工作,那么有一个叫做make的漂亮使用的工具可以帮助你(大多数*nix发行版都会提供)。使用条件编译,还有几个对编程来说非常好的特性,比方说允许你程序有不同的编译结果–举个例子,你可以拥有一个可调试和输出大量相关调试信息的版本。
  • 了解了编译过程和链接过程后就可以更容易的捕获到bugs了。编译错误往往是语法上的–缺失了一个分号啊,多了一个括号啊。链接错误往往来自于未定义或多重定义。如果你从编译器得到了一条函数或变量多次定义的错误,那么这就很好的说明了这个错误是因为在你的源代码文件中重复定义了一个变量或函数造成的。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值