c ++链接器是否会丢弃不需要的内容或仅添加所需内容?

时间:2015-03-16 15:37:29

标签: c++ linker

如果链接器开始满足丢失的符号,直到它到达满足所有需要的符号的点,我们称之为“仅添加所需的内容”。另一方面,从完整的符号集合开始,然后基于某些算法扫描以删除不需要的符号,我们称之为“投掷”。从语义上讲,我们将链接过程的这个方面描述为仅添加所需内容更为正确。

我很好奇stackoverflow社区同意这一点,因为我相信它依赖于这些链接器功能会有更强的论据。

4 个答案:

答案 0 :(得分:3)

所有连接子都以添加剂模式工作。最好用图论来解释。

链接器首先标识一个或多个入口点(main用于库的可执行,导出函数)。必须包含这些入口点。

但是,这些导出点可能包含在较大的段/块中(许多编译器不能或不能打包单个函数和数据)。包含在同一块/段中的任何内容都将自动包含在内。

此外,当函数调用其他函数时,链接器可能也需要添加这些函数 - 再次,编译器限制可能导致在块太大时拖入大量额外的东西。此步骤称为“解析依赖关系”,通常以递归方式完成,直到不再缺少任何函数。

为什么这些块太大了?常见问题是编译器/链接器对无法传递依赖关系。如果不能告诉链接器X依赖于Y,则编译器必须将X和Y放在同一段中。不幸的是,这往往会升级到整个.cpp文件在同一段中结束的程度 - 所有那些不需要的函数都会拖延到不需要的依赖项中。因为这个原因,我看到可执行文件会增加到600 MB。

答案 1 :(得分:2)

链接器解析引用。它们“查看”待链接目标文件的符号表,并解析这些引用 - 或者如果给定的目标文件都不满足所述引用,则吐出“未解析的引用”错误。

所以你有理由说他们正在“加入”。 (你的评论/编辑看到了你来自哪里。)

但是,有一些限制,具体取决于所使用的链接器的功能。您可能(并且可能是......)正在查看只能决定链接整个目标文件的链接器。在这种情况下,代码结构的 ,链接器是否可以很好地省略不需要的对象代码。如果您只拥有一个大对象文件,那么只要需要该对象文件中的单个符号,它就会被链接。

所以它可能比你想要的“添加”更多 - 或者“无法删除”。这真的只是在狡辩。

答案 2 :(得分:1)

你的问题的答案有很多"它取决于"。

例如,它取决于编译器和链接器的功能。一些链接器可能没有智能来检测未使用的功能。

如果优化级别设置为特定级别,某些编译器可能只会丢弃函数。

该函数可能必须是您正在构建的代码的一部分,或者在静态库中,以便编译器将其删除。

有些编译器可能会抛出库中的所有函数,无论它们是否需要;取决于优化级别。

取决于

举一个更专业的例子。

答案 3 :(得分:1)

传统上,链接器将首先添加您指定的目标文件的所有。然后它将通过静态链接库,查找定义这些目标文件或早期库所需符号的模块 - 定义符号的任何模块总共链接。未定义所需符号的模块未链接。

今天的链接器更复杂,并且能够执行优化步骤,但细节应该来自您正在使用的特定构建系统的文档。