16

次のコードがあるとします

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

コンパイラが生成したコードは、pvtableエントリをvirtualMethod1回または1000回逆参照しますか?Microsoftのコンパイラを使用しています。

編集

これが、私が見ている実際のケース用に生成されたアセンブリです。 line->addPoint()関心のある仮想的な方法です。組み立ての経験がないので、ゆっくりと調べていきます...

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

    test    ebx, ebx
    je  SHORT $LN1@RDS_SCANNE
    lea edi, DWORD PTR [ecx+32]
    npad    2
$LL3@RDS_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 $LL3@RDS_SCANNE
$LN314@RDS_SCANNE:

; 365  :        }
4

2 に答える 2

6

一般的に、いいえ、それは不可能です。*thisこの関数は、そのスペース内の同じベースから派生した他のオブジェクトを破壊して配置することができます。

編集:さらに簡単に、関数は単に変更される可能性がありますp. p問題の最適化ユニットに対してローカルでない限り、コンパイラは誰が のアドレスを持っているかを知ることはできません。

于 2013-02-07T17:50:12.080 に答える
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";
于 2013-02-07T19:04:21.097 に答える