2013-02-07 41 views
15

假设我有以下代码C++编译器能够在同一个指针上优化重复的虚拟函数调用吗?

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

将编译器生成的代码提领pvtable条目virtualMethod 1或1000倍?我正在使用微软的编译器。

编辑

这里是现实世界的情况下,我在看生成的程序集。 line->addPoint()是虚拟的关注方法。我没有装配经验,所以我正在慢慢地去...

; 369 :  for (int i = 0; i < numPts; ++i) 

    test ebx, ebx 
    je SHORT [email protected]_SCANNE 
    lea edi, DWORD PTR [ecx+32] 
    npad 2 
[email protected]_SCANNE: 

; 370 :  { 
; 371 :   double *pts = pPoints[i].SystemXYZ; 
; 372 :   line->addPoint(pts[0], pts[1], pts[2]); 

    fld QWORD PTR [edi+8] 
    mov eax, DWORD PTR [esi] 
    mov edx, DWORD PTR [eax+16] 
    sub esp, 24     ; 00000018H 
    fstp QWORD PTR [esp+16] 
    mov ecx, esi 
    fld QWORD PTR [edi] 
    fstp QWORD PTR [esp+8] 
    fld QWORD PTR [edi-8] 
    fstp QWORD PTR [esp] 
    call edx 
    add edi, 96     ; 00000060H 
    dec ebx 
    jne SHORT [email protected]_SCANNE 
[email protected]_SCANNE: 

; 365 :  } 
+5

要求编译器生成汇编代码并检查。 –

+1

通过优化编译并查看生成的生成代码。 – Petesh

+3

要添加到Joachim的评论 - *除了检查之外没有其他方法*。 –

回答

5

一般来说,不,这是不可能的。该函数可以销毁*this并放置新的一些其他对象,这些对象是从该空间中的相同基础派生的。

编辑:更容易,功能可以改变p。编译器不可能知道谁拥有地址p,除非它位于所讨论的优化单元的本地。

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"; 
+0

加1用于整个程序/链接时间优化,这使得'不可能'通常是微不足道的。 –

相关问题