C ++编译器可以在同一个指针上优化重复的虚函数调用吗?

时间:2013-02-07 17:12:56

标签: c++ performance polymorphism vtable

假设我有以下代码

void f(PolymorphicType *p)
{
    for (int i = 0; i < 1000; ++i)
    {
        p->virtualMethod(something);
    }
}

编译器生成的代码解除引用p的{​​{1}}条目vtable 1或1000次?我正在使用微软的编译器。

修改

这是我正在查看的真实案例的生成程序集。 virtualMethod是关注的虚拟方法。我没有装配经验,所以我慢慢地过去......

line->addPoint()

2 个答案:

答案 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";