2016-02-26 32 views
4

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

+0

未使用的'private'方法可能可以安全地删除。 – axiac

+1

@DevSolar:如果方法真的没有使用,我不明白这会对你产生什么影响。唯一的两种情况是在调试器中,如果你用vtable手动破解(你不应该这样做)。 –

+0

@JørgenFogh:我主要指的是“当方法是虚拟的时候,这变得非常有趣”,这似乎意味着一个概念,可能会有一个未明确提及的方式涉及破坏。如果你喜欢,可以提供“问题气味”。 ;-) – DevSolar

回答

1

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

顺便说一句,我只是寻找我的机器上的draft PDF,并且只有一个整个1368的页面文件中的单词“接头”,甚至认为一个实例仅仅是在约22页脚注字符集。

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

援引§1.9:

(...)符合实现需要模拟(仅) 观察到抽象机的行为如下面所解释。

在为这句话,脚注,它进一步说:

这一规定有时被称为“为假设”规则,因为 实现可以自由地忽略此 国际的任何要求标准,只要结果就好像 已经服从一样,就可以从程序的可观测的 行为中确定。

如果某个函数没有以任何方式在程序中的任何地方使用,那么它不会对可观察行为产生任何影响。单独的“as-if”规则使得编译器或链接器完全可以将其从可执行结果中移除。

5

是的。

如果该方法未被使用,那么就没有办法告诉它已被删除 - 所以链接器可以这样做。请注意,获取方法的地址可能会被视为“使用”方法 - 不仅仅是实际调用方法。

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

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

+1

如果能够创建一个库,那么如果这通常是真的,你会如何?图书馆主要由未使用的功能组成。 – tofro

+2

库(静态库)不是由链接器创建的。对于共享库,所有公共符号在导出时都是“使用”的。 –

1

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

编译器可以检查如何使用实例来检测未使用的虚拟成员,但这样做的好处很多。几年前,GCC没有这样做。

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

2

由于C++标准对此没有提及,所以说它可能更准确的说它不会阻止删除未使用的成员函数,而不是说它允许它们被删除。但同样有效的说,它不需要将其删除。顺便说一句,所有功能都是如此。

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

难度较大的实际问题可能是检测到非静态成员函数未被调用。更甚的是,如果它是虚拟的,因为对象的静态类型是决定调用虚拟函数的哪个重写。原则上检测这种情况并非不可能,但需要进行相当数量的分析。最终它会归结为构建链的实施质量,因为该标准没有特别要求。这取决于供应商是否选择实施这种优化。而且,由于这不是许多开发者实际寻求的行为(最有可能的人会寻求它会有一个过早的优化迷信)并不是很多。

相关问题