2012-09-13 61 views
5

使用下面的代碼,編譯器是否可以告訴a實際上是B的一個實例並優化虛擬表查找?虛擬表查找的優化

#include <iostream> 

class A 
{ 
    public: 
    virtual void f() 
    { 
     std::cout << "A::f()" << std::endl; 
    } 
}; 

class B : public A 
{ 
    public: 
    void f() 
    { 
     std::cout << "B::f()" << std::endl; 
    } 
}; 

int main() 
{ 
    B b; 
    A* a = &b; 
    a->f(); 

    return 0; 
} 
Jonthan恆生和reima的答案後

其他問題:在使用GCC的情況下,有必要使用任何標誌,迫使它來優化虛函數表查找?

+0

找出肯定的唯一方式是看裝配。但是,是的,devirtualization是標準的編譯器優化。 – Mysticial

+0

剛剛爲GCC添加了反彙編。我使用'-O1'標誌進行基本的優化。 – reima

回答

5

Clang可以很容易地進行這種優化,甚至內聯函數調用。這可以從生成的彙編中可以看出:

Dump of assembler code for function main(): 
    0x0000000000400500 <+0>: push %rbp 
    0x0000000000400501 <+1>: mov %rsp,%rbp 
    0x0000000000400504 <+4>: mov $0x40060c,%edi 
    0x0000000000400509 <+9>: xor %al,%al 
    0x000000000040050b <+11>: callq 0x4003f0 <[email protected]> 
    0x0000000000400510 <+16>: xor %eax,%eax 
    0x0000000000400512 <+18>: pop %rbp 
    0x0000000000400513 <+19>: retq 

我把由等效調用替換std::cout << …printf,因爲這極大地減少了在拆卸雜波的自由。

GCC 4.6也可以推斷出不需要虛函數表的查找,但不在線:

Dump of assembler code for function main(): 
    0x0000000000400560 <+0>: sub $0x18,%rsp 
    0x0000000000400564 <+4>: mov %rsp,%rdi 
    0x0000000000400567 <+7>: movq $0x4007c0,(%rsp) 
    0x000000000040056f <+15>: callq 0x400680 <B::f()> 
    0x0000000000400574 <+20>: xor %eax,%eax 
    0x0000000000400576 <+22>: add $0x18,%rsp 
    0x000000000040057a <+26>: retq 
+0

+1 Visual Studio 2010也將其虛擬化。但它沒有內聯。 – Mysticial

+0

我目前只有gcc 4.4。它似乎並不與-O3甚至優化查詢: SUBQ \t $ 24%RSP .cfi_def_cfa_offset 32​​ MOVQ \t $ _ZTV1B + 16(%RSP) MOVQ \t%RSP,%RDI 呼叫\t * _ZTV1B +16(%RIP) xorl \t%EAX,EAX% addq \t $ 24%RSP .cfi_def_cfa_offset 8 RET – Ruup

+1

螺絲吧!只是不能格式化它! – Ruup

-2

也許它可以 - 這取決於編譯器的智慧和優化要求。

但是,這是一個電話。你爲什麼關心優化這個呼叫?而且,如果你確實在意,爲什麼不直接爲這一個電話獲取類型?

有關優化的所有問題的第一個答案是,「爲什麼你需要優化?」有一個表現工具報告說50%的申請時間是一個地方,並且問題得到解答。 「哦,但它效率低下,」最常見的答案,導致不可維護的代碼,很少優化實際上效率低下的代碼。

+1

我沒有downvote,但如果OP不在乎,這個問題就不會被問到。 – Mysticial

+2

當沒有理由時,人們經常關心優化。所以,我會從中提出一個問題。 –

+0

答案會在評論中出現.. –