Visual c++ MSVC编译器与&;用于COMDAT折叠的链接器选项

Visual c++ MSVC编译器与&;用于COMDAT折叠的链接器选项,visual-c++,compiler-construction,linker,comdat-folding,Visual C++,Compiler Construction,Linker,Comdat Folding,这个问题有一些答案,但我的答案略有不同。在标记为复制品之前,请试一试 MSVC始终提供/Gy编译器选项,以便将相同的函数折叠到COMDAT节中。同时,链接器还提供/OPT:ICF选项。我的理解是否正确,这两个选项必须结合使用?也就是说,虽然前者将功能打包到COMDAT中,但后者消除了冗余COMDAT。对吗 如果是,那么我们要么同时使用,要么同时关闭?如 如/Gy文件中所述,功能级链接 允许在“未使用的函数”过程中丢弃函数, 如果您通过/OPT:REF请求它,它不会改变实际的经典 链接的模型。标志

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

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

如果是,那么我们要么同时使用,要么同时关闭?

如/Gy文件中所述,功能级链接 允许在“未使用的函数”过程中丢弃函数, 如果您通过/OPT:REF请求它,它不会改变实际的经典 链接的模型。标志名称具有误导性。这不是“表演” 功能级链接”。它只是通过告诉链接器来启用它 函数开始和结束的位置。它不是那么多的功能级别 链接,因为它是功能级别的取消链接-雷蒙德

(这个片段在更进一步的上下文中可能更有意义:以下是关于经典链接模型的帖子:


简而言之,是的。如果您激活一个开关而不激活另一个,则不会产生明显的影响。

请与我进行离线交流的人回答。这有助于我更好地理解这些选项

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

这是真的。假设我们只讨论C或C++,但没有成员函数。没有/Gy,编译器创建的对象文件在某种意义上是不可约的。如果链接器只从对象中得到一个函数,则将它们全部获取。这是在库编程中特别考虑的一个问题,如果你想对它友好的话。对于库的用户,您应该将库编写为许多小对象文件,通常每个对象有一个非静态函数,这样库的用户就不会因为必须携带实际上从未执行过的代码而感到臃肿

使用/Gy,编译器创建具有COMDAT的对象文件。每个函数都在其自己的COMDAT中,这在某种程度上是一个迷你对象。如果链接器只需要从对象中选择一个函数,它可以只选择该函数。链接器的/OPT开关使您能够控制链接器在这种选择性下执行的操作-但如果没有/Gy,则没有无需选择

或者很少。至少可以想象,链接器可以,例如,在一个对象文件中折叠每个函数都是整个代码,并且恰好有相同的代码。当然可以想象,链接器可以删除一个不包含任何引用的整个对象文件。毕竟,它是通过对象文件来实现的n个库。然而,实践中的规则是,如果您将非COMDAT对象文件添加到链接器的命令行,那么即使未引用,您也表示希望该文件以二进制形式存在。可以想象的内容与完成的内容之间的差异通常是巨大的

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


==========================================================/p>是的,在编译器和链接器中这样做有点过分。/OPT:ICF非常昂贵,您可以选择提供迭代参数以使链接时间保持合理。这样做的可能原因是。