为什么vtable包含重复的功能?

时间:2015-09-01 18:42:34

标签: c++ compiler-optimization vtable

想象一个项目,其中有一个类似于以下的接口类:

struct Interface
{
    virtual void f()=0;
    virtual void g()=0;
    virtual void h()=0;
};

假设在其他地方,有人希望创建一个实现此接口的类,fgh都做同样的事情。

struct S : Interface
{
    virtual void f() {}
    virtual void g() {f();}
    virtual void h() {f();}
};

然后,为S生成vtable是一个有效的优化,其条目都是指向S::f的指针,从而保存对包装函数g和{{1}的调用}。

但是,打印vtable的内容表明不执行此优化:

h
  

0x400940
  0x400950
  0x400970

使用S s; void **vtable = *(void***)(&s); /* I'm sorry. */ for (int i = 0; i < 3; i++) std::cout << vtable[i] << '\n'; -O3进行编译无效,clang和gcc之间的切换也是如此。

为什么错过了这个优化机会?

目前,这些是我考虑(并拒绝)的猜测:

  1. vtable打印代码实际打印垃圾。
  2. 性能提升被认为毫无价值。
  3. ABI禁止它。

1 个答案:

答案 0 :(得分:2)

此类优化无效,因为......

// somewhere-in-another-galaxy.hpp
struct X : S {
    virtual void f();
};

// somewhere-in-another-galaxy.cpp
include <iostream>
void X::f() {
    std::cout << "Hi from a galaxy far, far away! ";
}

如果编译器实现了优化,则此代码将无效。

Interface* object = new X;
object->g();

我的翻译单元的编译器不知道你的类内部实现,所以对于g()和h()它只是放入我的班级&#39;虚函数表引用您班级中的相应条目&#39; VFT。