2012-02-04 49 views
1

如果我在C這種情況++項目:C++中的單個虛擬繼承編譯器優化?

  • 1的基類「基地」只含有純虛函數
  • 1類「派生」,這從「Base是繼承了唯一的類(公共) '

編譯器會生成一個VTABLE嗎?

似乎沒有必要,因爲項目只包含一個Base *指針可能指向的(Derived)類,所以這可以解決所有情況下的編譯時間。

如果您想爲單元測試執行依賴注入,但不希望在生產代碼中產生VTABLE查找成本,這很有趣。

+2

編譯器不會知道它的基類會在另一個源文件中被繼承,所以它可能會添加一個vtable。 – 2012-02-04 12:27:44

+0

噢,對,可以想到,你的答案似乎是正確的。所以看起來我不會使用指向虛擬基類的指針來註冊依賴關係,而是給我的測試類使用與生產依賴關係相同的名稱,並有條件地在單元測試中編譯我的測試類(和我的生產類)。 .. – Sjimmie 2012-02-04 12:38:51

+0

[爲什麼當派生類不重寫虛函數時需要VTABLE?](http://stackoverflow.com/questions/9109662/why-is-a-vtable-required-when-派生類不包含虛擬樂趣) – 2012-02-04 14:55:54

回答

5

我沒有硬數據,但我有很好的理由說不,它不會將虛擬呼叫變成靜態數據。

  • 通常,編譯器只能看到一個編譯單元。它不知道只有一個子類,因爲五個月後你可以編寫另一個子類,編譯它,從備份中獲得一些古老的目標文件並將它們連接在一起。
  • 雖然鏈接時間優化確實看到了整個畫面,但它們通常在程序的低層次表示上工作。這種表示允許例如內聯靜態調用,但不代表繼承信息(可能除外可選元數據),並已明確顯示虛擬調用和vtables。 I 知道 Clang和IIRC的情況gcc的整個程序優化也適用於某些低級IR(GIMPLE?)。
  • 另請注意,通過動態加載,您仍然可以在編譯和LTO之後的仍然添加更多的子類。你可能不需要它,但是如果我是一個編譯器編寫者,我會厭倦添加一個優化,讓人們在非常特定的,難以追蹤的情況下大量打破虛擬呼叫。
  • 這很難解決 - 如果你不需要虛擬呼叫(例如因爲你知道你不需要更多的子類),請不要製造東西virtual。檢查你的設計。如果你需要一些多態性,但不是虛擬的全部力量,curiously recurring template pattern可能會有所幫助。
+1

謝謝,你引發了我尋找一個編譯時多態解決方案,並有人已經有我認爲我可以使用的東西:http://skepticalmethodologist.wordpress.com/2008/07/20/dependency-injection-in-c/ – Sjimmie 2012-02-04 12:55:31

0

編譯器根本不必使用基於虛擬功能調度的基於vtable的實現,因此對於您的問題的答案將特定於您正在使用的實現。

+0

我使用gcc,它有一個優化選項列表:http://gcc.gnu.org/onlinedocs/gcc-3.4.5/gcc /Optimize-Options.html。但我無法找到似乎適用的一個。關鍵是'可能'不是真的可以接受的。 – Sjimmie 2012-02-04 12:26:30

+0

@Sjimmie:我的猜測是它不會優化它。你有沒有檢查編譯好的代碼? – 2012-02-04 12:34:41

0

V表通常不僅用於虛擬功能,但它也可以用來識別類的類型,當你做一些dynamic_cast或當程序訪問type_info爲類。

如果編譯器檢測到沒有虛擬函數需要動態分派,並且沒有使用其他功能,則它可以將優先級作爲優先級移除。

很顯然,編譯器編寫者並沒有發現這樣做的麻煩。可能是因爲它不會經常使用。