28

只是好奇,GCC 或 Clang 工具集目前是否实现了与 MSVC相同的 COMDAT 折叠(ICF) 等效的功能?如果没有,有什么计划吗?除了旧的 GCC 邮件列表消息之外,我似乎找不到任何关于该主题的最新权威链接。

如果不是,这是否意味着不同类型上的模板实例化始终是生成的二进制文件中的不同函数(在它们未完全内联的情况下),即使它们是二进制兼容的,或者是否有其他机制来处理这个在其他级别?

另外,有没有人发现 ICF 在实践中最小化生成的可执行文件的大小有很大的不同?我没有任何大型 MSVC 项目可以方便地对其进行测试。(我猜它只有在你碰巧在许多不同的 vtable-layout 兼容类型上实例化模板时才真正有帮助。)

最后,两个指向不同函数的函数指针在运行时比较相等是否符合 C++11 标准?这个链接似乎暗示它不是,但它适用于 C99。编辑:找到有关此主题的先前问题

4

1 回答 1

20

GCC 和 Clang 都不是链接器,ICF 需要由链接器完成,或者至少需要与链接器合作。编辑:他们不做 ICF,所以是的,不同的实例化产生不同的代码。GNUgold链接器通过选项支持 ICF,该--icf选项需要使用 GCC 选项-ffunction-sections

不同的函数必须有不同的地址......我不记得是否为任何获取其地址的函数禁用了 ICF,但如果不是,应该可以在组合函数之前放置大量无操作指令并使每个不同的实例化从不同的指令开始,因此它们具有不同的地址。编辑:gold 的--icf=safe选项仅对可以证明其地址未被占用的函数启用 ICF,因此依赖于不同地址的代码仍然可以工作。

ICF 是一种巧妙的优化,但不是必需的。通过一些努力,您可以将非依赖代码提升到非模板或具有较少参数的模板,以减少可执行文件中重复代码的数量。在我几年前做的饮食模板演讲的幻灯片中有更多信息。

于 2013-03-02T00:15:14.213 回答