假设我有以下代码
void f(PolymorphicType *p)
{
for (int i = 0; i < 1000; ++i)
{
p->virtualMethod(something);
}
}
编译器生成的代码解除引用p
的{{1}}条目vtable
1或1000次?我正在使用微软的编译器。
修改
这是我正在查看的真实案例的生成程序集。 virtualMethod
是关注的虚拟方法。我没有装配经验,所以我慢慢地过去......
line->addPoint()
答案 0 :(得分:6)
一般来说,不,这是不可能的。该函数可能会破坏*this
和放置 - 从该空间中的同一基础派生的一些其他对象。
编辑:更简单,该功能可以更改p
。编译器不可能知道谁具有p
的地址,除非它对于所讨论的优化单元是本地的。
答案 1 :(得分:2)
一般情况下不可能,但有一些特殊情况可以优化,特别是在程序间分析方面。具有完全优化和整个程序优化的VS2012编译了该程序:
#include <iostream>
using namespace std;
namespace {
struct A {
virtual void foo() { cout << "A::foo\n"; }
};
struct B : public A {
virtual void foo() { cout << "B::foo\n"; }
};
void test(A& a) {
for (int i = 0; i < 100; ++i)
a.foo();
}
}
int main() {
B b;
test(b);
}
为:
01251221 mov esi,64h
01251226 jmp main+10h (01251230h)
01251228 lea esp,[esp]
0125122F nop
01251230 mov ecx,dword ptr ds:[1253044h]
01251236 mov edx,12531ACh
0125123B call std::operator<<<std::char_traits<char> > (012516B0h)
01251240 dec esi
01251241 jne main+10h (01251230h)
所以它有效地优化了循环:
for(int i = 0; i < 100; ++i)
cout << "B::foo()\n";