是否允许C ++编译器/链接器删除未使用的方法?

时间:2016-02-26 09:49:18

标签: c++ optimization methods

C ++编译器或链接器(通过任何C ++标准)是否允许删除未使用的方法? 似乎允许编译器删除未使用的静态函数,允许链接器删除未使用的函数。但我没有找到任何信息类似于方法的信息。当方法是虚拟的时,这真的很有趣。

4 个答案:

答案 0 :(得分:5)

是。

如果方法未使用,则无法判断它是否已被删除 - 因此链接器可以这样做。请注意,获取方法的地址可能会被视为“使用”该方法 - 而不仅仅是实际调用它。

链接器很可能会删除非虚拟成员函数(它很容易并节省空间)。

他们可以删除未使用的虚函数,但编译器必须添加大量有关它正在调用的虚函数的信息,以便链接器可以删除未使用的虚函数(并可能压缩vtable) 。在实践中,我不认为链接器这样做是因为增益可能很小而且需要的开发工作量相当大。

答案 1 :(得分:2)

由于C ++标准对此没有任何说明,因此可能更准确地说不会阻止删除未使用的成员函数,而不是说它允许删除它们。但同样有效的说它不需要删除它们。顺便说一下,这对于所有功能都是如此。

如果构建链中的程序(编译器,链接器等)可以检测到没有使用任何符号(例如静态或非静态成员函数),它可以安全地删除它们。

更难的实际问题可能是检测到没有调用非静态成员函数。更重要的是,如果它是虚拟的,因为对象的静态类型决定了调用虚拟函数的哪个覆盖。原则上检测此类情况并非不可能,但需要进行大量分析。

最终,它将归结为构建链的实施质量,因为标准不需要特别的任何内容。这取决于供应商是否选择实施此类优化。并且,由于这不是许多开发人员实际寻求的行为(最有可能寻求它的人会有过早的优化迷信)并不是很多人会这样做。

答案 2 :(得分:1)

类方法在类定义中定义时会被内联。当它们单独实现时,它们是具有隐藏的第一个参数this的简单函数,它成为指向将该函数作为其类的成员调用的实例的指针。删除未使用的类方法没有问题。

编译器可以检查实例的 vtable 如何用于检测未使用的虚拟成员,但这是为了获得小的好处而进行的大量跟踪。几年前,GCC没有这样做。

关键字volatile或导出保存变量&删除优化的函数/类方法。

答案 3 :(得分:1)

C ++标准在更抽象的层面上运作。它不需要C ++实现实际上由编译器和链接器等单个工具组成。

顺便说一下,我刚搜索了我机器上的draft PDF,并且在整个1368页的文档中只有一个单词“linker”的实例,甚至那个是只是在第22页的脚注中关于字符集。

标准实际上谈的是所谓的“as-if”规则

引用§1.9:

  

(...)符合要求的实现需要模拟(仅)   抽象机器的可观察行为,如下所述。

在该句的脚注中,它进一步说:

  

这项规定有时被称为“as-if”规则,因为a   实施可以自由地忽视任何要求   国际标准只要结果就好像要求一样   已经遵守,只要可以从观察中确定   该计划的行为。

如果函数未以任何方式在程序的任何位置使用,则它不会对可观察行为产生任何影响。因此,“as-if”规则使编译器或链接器完全自由地将其从可执行结果中删除。