想象一个项目,其中有一个类似于以下的接口类:
struct Interface
{
virtual void f()=0;
virtual void g()=0;
virtual void h()=0;
};
假设在其他地方,有人希望创建一个实现此接口的类,f
,g
,h
都做同样的事情。
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之间的切换也是如此。
为什么错过了这个优化机会?
目前,这些是我考虑(并拒绝)的猜测:
答案 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。