消除未使用的虚函数。

3
为了消除未使用的(普通)函数,我可以使用以下选项:-ffunction-sections、-fdata-section和--gc-sections。并且它是有效的。
我知道使用多态,函数是“延迟绑定”的,所以我想在链接过程中没有办法决定哪个函数可以被移除。
但我使用纯虚函数来强制要求继承类实现某些函数。然后在代码中,我使用对象(而不是指针/引用对象),所以我没有使用多态。
伪代码如下:
class BASE {
    ...
    virtual void do_sth() = 0;
    virtual void do_sth_else() = 0;
    ...
};

class C1 : BASE {
    ...
    void do_sth() { //some code }
    void do_sth_else() { //some code }
}

main()
{
    //the do_sth_else function is never used in main
    C1 obj1;
    obj.do_sth();
}

在链接过程中有没有一些方法可以消除这些未使用的函数(do_sth_else)?也许我误解了什么,因为我认为应该有一种方法来删除这个未使用的函数。如果可以,请解释一下当我不使用带有虚拟函数指针时,为什么没有办法"摆脱"多态开销。

顺便提一下,此代码主要是用于学习目的。


5
如果你没有使用指针或引用,并且基本上没有动态派发,那么为什么要使用virtual呢?似乎你误解了virtual。阅读在C++中何时将函数标记为虚拟?会是一个不错的选择。 - Alok Save
我同意你关于“虚函数”的“虚假”使用的看法。我理解多态,但我想强制继承类实现一些函数。我知道在这种情况下使用模板是另一种解决方案。换句话说,我更愿意使用虚函数而不是多态。为什么我要使用它并不是很重要,我更想学习和理解为什么我无法在链接期间摆脱这个函数。 - qubu
2
你似乎忘记给 main 指定返回类型。GCC 应该能够“去虚拟化”那些函数调用,因为对象的动态类型是已知的,但是如果没有像 -fwhole-program 这样的东西,它不太可能丢弃未使用的虚拟函数,因为另一个翻译单元可能需要它们的定义。 - Jonathan Wakely
2个回答

4
感谢Jonathan Wakely,我开始查找并找到了GCC选项:

-fvtable-gc 为vtable和虚拟函数引用发出特殊的重定位,以便链接器可以识别未使用的虚拟函数并将引用它们的vtable槽清零。这对于 -ffunction-sections 和 -Wl,--gc-sections 最有用,以便也丢弃函数本身。

但在GCCv4.7.1中不支持。


-1

为了学习目的,我建议你学习语言元素的语义,并学会根据它们的目的使用它们。也就是说,在你希望使用多态性的地方使用虚拟函数,否则就不要去碰它们。

担心连接器留下的无用代码量这样的事情可以安全地留给未来的5-10年或永远不管。

而且优化每年都在改进,所以即使今天你可能发现图像中有0.01%的可能浪费,到达生产阶段时它可能会自己消失。


1
我知道优化通常每年都有改进,而且其他编译器处理某些情况的方式也不同于gcc...我通常使用uC和C代码工作。我正在进行一些关于C++的实验,并尝试关注在一些特殊条件下C++的开销。但还是感谢您的回答。 - qubu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接