在C++中,大部分優化是從as-if規則派生的。也就是說,只要程序的行爲如果沒有發生優化,那麼它們就是有效的。空數據會員優化:有可能嗎?
的空基地優化是一個這樣的特技:在某些條件下,如果基類爲空(沒有任何非靜態數據成員),則編譯器可其的Elid內存中的表示。
顯然,這似乎是標準禁止在數據成員這種優化,也就是即使一個數據成員是空的,但它仍然必須採取的地方至少有一個字節值:從n3225,[類]
4 - 類類型的完整對象和成員子對象的大小不爲零。
注:這導致使用私有繼承的政策設計,以有EBO踢在適當的時候
我在想,如果使用AS-if規則,一個可能仍然是能夠執行此優化。
編輯:以下一些答案和意見,並作出更清楚什麼,我想知道。
首先,讓我舉一個例子:
struct Empty {};
struct Foo { Empty e; int i; };
我的問題是,爲什麼sizeof(Foo) != sizeof(int)
?特別是,除非你指定了一些包裝,否則可能是由於對齊問題,Foo將會是int的兩倍,這似乎是可笑的膨脹。
注:我的問題不是爲什麼sizeof(Foo) != 0
,這實際上並非EBO要麼
需要根據C++,這是因爲沒有子對象可以具有零大小。然而鹼被授權具有零大小(EBO)因此:
struct Bar: Empty { int i; };
可能(由於EBO)服從sizeof(Bar) == sizeof(int)
。
Steve Jessop似乎認爲這是因爲沒有兩個子對象會有相同的地址。我想過這個問題,但它實際上並沒有阻止在大多數情況下,優化:
如果你有「未使用」的內存,那麼它很簡單:
struct UnusedPadding { Empty e; Empty f; double d; int i; };
// chances are that the layout will leave some memory after int
但事實上,它甚至「雪上加霜「比那,因爲Empty
空間永遠不會被寫入(你最好不要,如果EBO踢... ...),因此你實際上可以將其放置在一個被佔領的地方,是不是另一個對象的地址:
struct Virtual { virtual ~Virtual() {} Empty e; Empty f; int i; };
// most compilers will reserve some space for a virtual pointer!
或者,即使在我們最初的情況:如果我們所有
struct Foo { Empty e; int i; }; // deja vu!
人能(char*)foo.e == (char*)foo.i + 1
想要的是不同的地址。
查看Boost的[Compressed Pair](http://www.boost.org/doc/libs/1_45_0/libs/utility/compressed_pair.htm)庫,瞭解如何獲得此優化。 – GManNickG 2011-01-07 09:58:03
@GMan:他們巧妙地使用EBO。但實際上,這種EBO的使用正是促使我的問題開始的原因。 – 2011-01-07 10:07:58
請參閱:[什麼時候程序員使用空基優化(EBO)](http://stackoverflow.com/questions/4325144/scenario-when-do-programmers-use-empty-base-optimization-ebo) – Nawaz 2011-01-07 10:33:57