这个问题在SO上有一些答案但我的略有不同。在标记为重复之前,请试一试。
MSVC始终提供/ Gy 编译器选项,以便将相同的功能折叠到COMDAT部分。同时,链接器还提供/ OPT:ICF选项。我的理解是正确的,这两个选项必须结合使用吗?也就是说,虽然前者的包运行到COMDAT中,但后者消除了冗余的COMDAT。这是对的吗?
如果是,那么我们要么使用两者还是关掉两者?
答案 0 :(得分:1)
与我离线沟通的人的回答。帮助我更好地理解这些选项。
===================================
基本上是这样。假设我们只讨论C或C ++,但没有成员函数。如果没有/ Gy,编译器会创建在某种意义上不可简化的目标文件。如果链接器只需要来自对象的一个函数,那么它将全部获取。这是图书馆编程时的一个特殊考虑因素,如果您想对图书馆用户表示友好,您应该将图书馆编写为许多小对象文件,通常每个对象一个非静态函数,这样库的用户不必承担实际上从未执行过的代码。
使用/ Gy,编译器会创建具有COMDAT的目标文件。每个函数都在自己的COMDAT中,这在某种程度上是一个迷你对象。如果链接器只需要来自对象的一个函数,它就可以选择那个函数。链接器的/ OPT开关可以让你控制链接器对这种选择性的作用 - 但没有/ Gy就没有什么可以选择的。
或者很少。至少可以想象,链接器可以例如折叠每个目标文件中的整个代码的函数,并且碰巧具有相同的代码。当然可以想象链接器可以消除整个目标文件,其中不包含任何引用的文件。毕竟,它使用库中的目标文件来完成此操作。然而,实践中的规则曾经是,如果您将非COMDAT对象文件添加到链接器的命令行,那么即使未引用,您仍然希望在二进制文件中使用该文件。什么是可以想象的和做了什么之间的区别通常是巨大的。
那么,最好坚持快速回答。链接器选项可以从每个目标文件内部分离函数(和变量),但分离取决于组织到COMDAT中的代码和数据,这是编译器的工作。
===================================
答案 1 :(得分:0)