当导师入门级程序员时,我被问到这个问题,我正在考虑这个编译+链接过程如此官方和通常,我从来没有想过为什么。
我能想到的一件事是提高开发效率,但是还有其他更多与编译器相关的原因吗?
答案 0 :(得分:13)
效率。 编译程序时,为每个源文件创建一个目标文件,如果更改源文件,则只需重新编译该模块然后重新链接(重新链接很便宜)。 如果编译器在一次传递中完成所有操作,则必须为每次更改重新编译所有内容。
它也符合unix的小程序理念,它做一件事,所以你有一个预处理器,一个编译器,一个链接器,一个库创建者。这些步骤现在可能是同一工具的不同模式。
但是有理由说你希望编译器在一个步骤中链接,如果允许编译器在链接时更改目标文件,你可以做一些优化 - 大多数现代编译器都允许这样做,但它需要额外的在编译时将信息写入目标文件。
如果编译器可以将整个项目存储在单个数据库中,而不是混乱的源,资源,浏览信息文件,目标文件等,那会更好 - 但开发人员非常保守!
答案 1 :(得分:2)
部分原因是历史性的。回到黑暗时代,计算机几乎没有记忆。很容易创建一个包含足够源代码的程序,所有这些代码都无法一次处理。因此,处理必须分阶段完成:预处理源代码,将源代码编译为汇编(逐个),汇编到目标代码,链接到最终可执行文件的所有目标文件。每个步骤都有一个或多个独立工具来完成其任务。多年来,这些工具逐步得到改进,但过程中没有重大的重新设计成为主流。
答案 2 :(得分:2)
即使对于一个非常大的项目,构建时间也要低于24小时。能够在一夜之间建立更好。 单独编译,即将程序划分为“编译单元”并独立编译,是减少构建时间的方法:
如果编译单元没有被更改,并且如果它没有改变,则可以重用旧编译的结果。
您通常可以并行编译多个单元,甚至可以通过工作站网络进行分发。卑微的Make将并行编译,并且存在其他工具如ccdist
来分发编译工作。
链接本身并没有什么好处,但是必须使用单独编译的结果。
答案 3 :(得分:2)
教你的关于单一责任原则的门徒是多么美好的时光!
答案 4 :(得分:-3)
编译文件会将代码更改为计算机可以读取的二进制文件。链接文件告诉计算机如何完成命令。因此,如果没有这两个步骤,就无法立即生成所有内容。