MSVC Compiler& COMDAT折叠的链接器选项

时间:2016-11-11 19:29:00

标签: visual-c++ compiler-construction linker comdat-folding

这个问题在SO上有一些答案但我的略有不同。在标记为重复之前,请试一试。

MSVC始终提供/ Gy 编译器选项,以便将相同的功能折叠到COMDAT部分。同时,链接器还提供/ OPT:ICF选项。我的理解是正确的,这两个选项必须结合使用吗?也就是说,虽然前者的包运行到COMDAT中,但后者消除了冗余的COMDAT。这是对的吗?

如果是,那么我们要么使用两者还是关掉两者?

2 个答案:

答案 0 :(得分:1)

与我离线沟通的人的回答。帮助我更好地理解这些选项。

===================================

基本上是这样。假设我们只讨论C或C ++,但没有成员函数。如果没有/ Gy,编译器会创建在某种意义上不可简化的目标文件。如果链接器只需要来自对象的一个​​函数,那么它将全部获取。这是图书馆编程时的一个特殊考虑因素,如果您想对图书馆用户表示友好,您应该将图书馆编写为许多小对象文件,通常每个对象一个非静态函数,这样库的用户不必承担实际上从未执行过的代码。

使用/ Gy,编译器会创建具有COMDAT的目标文件。每个函数都在自己的COMDAT中,这在某种程度上是一个迷你对象。如果链接器只需要来自对象的一个​​函数,它就可以选择那个函数。链接器的/ OPT开关可​​以让你控制链接器对这种选择性的作用 - 但没有/ Gy就没有什么可以选择的。

或者很少。至少可以想象,链接器可以例如折叠每个目标文件中的整个代码的函数,并且碰巧具有相同的代码。当然可以想象链接器可以消除整个目标文件,其中不包含任何引用的文件。毕竟,它使用库中的目标文件来完成此操作。然而,实践中的规则曾经是,如果您将非COMDAT对象文件添加到链接器的命令行,那么即使未引用,您仍然希望在二进制文件中使用该文件。什么是可以想象的和做了什么之间的区别通常是巨大的。

那么,最好坚持快速回答。链接器选项可以从每个目标文件内部分离函数(和变量),但分离取决于组织到COMDAT中的代码和数据,这是编译器的工作。

===================================

答案 1 :(得分:0)

Raymond Chen in Jan 2013

回答
  

如/ Gy,功能级链接的文档中所述   允许在"未使用的功能期间丢弃功能"通过,   如果你通过/ OPT:REF要求它。它并没有改变实际的经典   链接模型。标志名称具有误导性。它不是"表演   功能级链接"。它只是通过告诉链接器来启用它   功能开始和结束的地方。而且它的功能水平并不高   链接,因为它是功能级别的链接。 -Raymond

(这个代码段可能更有意义,有一些进一步的背景:这里有关于经典链接模型的帖子:12

简而言之 - 是的。如果激活一个开关而没有另一个开关,则不会产生任何可观察到的影响。