C++標準規定單個訪問節中的成員變量必須按照它們聲明的順序排列在內存中。同時,編譯器可以自由選擇訪問節本身的相互順序。這種自由使理論上不可能鏈接由不同編譯器創建的二進制文件。那麼嚴格的內部排序的剩餘原因是什麼?並且即將推出的C++ 09新的C++ 11標準提供了一種「手工」完全確定對象佈局的方法嗎?C++中的類佈局:爲什麼會員有時會訂購?
回答
這種自由使理論上不可能鏈接由不同編譯器創建的二進制文件。
由於諸多原因,結構佈局最不重要。的operator new
和delete
,數據類型大小虛函數表,實現...
那麼,什麼是嚴格的截面訂貨剩餘原因是什麼?
C兼容性,我會想到,這樣在C中定義的結構體包它在C++ 以同樣的方式對一個給定的編譯器設置。
標準提供了一種「手工」完全確定對象佈局的方法嗎?
不,不超過現行標準。
對於class
或struct
沒有vtable和完全私人(或公共)字段,但是,如果您使用[u]int[8|16|32|64]_t
類型,則已可能。你有什麼使用情況比這更多?
>你有什麼使用情況比這更多? 優化。通過重新排序數據成員,可以使對象變小。代碼中的順序通常反映了邏輯組的成員,所以你不想改變它。 – 2008-11-14 13:37:22
編輯:我怕我誤解你的問題
我認爲這對內存訪問的優化。 例如,如果我們有這樣的結構:
struct example
{
int16 intData;
byte byteData;
int32 intData;
byte intData;
int32 intData;
}
讓我們假設在這個平臺上的字都是32位。然後,你將需要4個完整的單詞來通過在結構中的所有數據:
INT16 +字節= 24位(NETX場不適合在這裏)
INT32 = 32位(NETX場不適合在這裏)
字節= 8個比特(NETX場不適合在這裏)
INT32 = 32位
但是,如果重新排列場s到:
struct example
{
int16 intData;
byte byteData;
byte intData;
int32 intData;
int32 intData;
}
然後你可以保存一個內存訪問。
[編輯] 我今天新學到了一些東西!發現了以下標準報價:
一個 (非聯合)類的非靜態數據成員聲明沒有 居間訪問說明符被分配 這樣以後構件具有類 對象內 高地址。的由 訪問說明符分離 非靜態數據成員分配的順序是不確定的 (11.1)。執行對齊 要求可能會導致兩個相鄰的 成員不會立即被分配到 之後;因此可能需要 來管理虛擬功能(10.3)和虛擬 基類(10.1)。
有趣的 - 我不知道爲什麼這種自由度給出。繼續TH我以前的答覆的休息...
如前所述,對於維護訂購的原因是C兼容性,那時候我想的重新排序成員的利益沒有人想到,在內存佈局是典型的做法無論如何。另外,現在被認爲是「醜陋的技巧」(比如使用memset將選定的成員歸零,或者具有兩個具有相同佈局的結構)是相當普遍的。
該標準不給你一個方法來強制執行給定的佈局,但大多數編譯器提供的措施來控制填充,例如MSVC編譯器上的#pragma包。
其原因自動填充是平臺的可移植性:不同的體系結構有不同的對齊要求,例如有些體系結構會導致錯誤的整數(這是當時的簡單情況)。
Nah,我很確定他是對的。我無法查閱這裏的標準來查看它,但我之前也注意到了這一點。它說,不同訪問節之間的順序是未指定的,但是在一節中,成員按聲明的順序排列。我也想知道點是什麼 – jalf 2008-11-14 11:22:31
您不應該鏈接由不同編譯器創建的對象。即使您所談論的內容發生了變化,您仍然會遇到更多問題,導致您無法與其他編譯器生成的文件進行鏈接。 (對齊,命名修改,調用約定只命名其中的幾個)。
一個原因編譯器可以自由訂購訪問欄目周圍可能是這樣的編譯器可以建立在接入部分的順序爲:低地址成員比更高地址的成員更受保護,例如。
如果不允許重新排序,你不會得到任何東西:只有莢提供C兼容性和辦法給你一個字節類/結構內成員的偏移量(使用宏offsetof
),或者讓你memcpy的他們。如果您定義了自定義構造函數,複製構造函數,私有成員或其他內容,類型將變爲非POD。特別是,從一個類派生出來的當前打破了PODness。
C++ 1x降低了對POD的要求。例如,在C++中,1x std::pair<T, U>
實際上是一個POD,儘管它提供了自己的構造函數(但必須符合某些規則)。
- 1. 訂購工會
- 2. c/C++爲什麼有時會強調爲什麼有時沒有下劃線?
- 3. Android動畫布局訂購
- 4. 爲什麼添加線性佈局(Android)時會出現nullpointerexception?
- 5. 爲什麼我會有沒有會員錯誤
- 6. 根據訂購的物品設置總數,有兩種類型,有時一種類型不會訂購。
- 7. 爲什麼Scala List沒有訂購?
- 8. GAE回購爲什麼會掛?
- 9. 爲什麼我的ScrollViewer會破壞我的網格佈局? WPF
- 10. WordPress的訂單不會訂購文章
- 11. ng-model爲什麼有時會預先填充,有時不會?
- 12. 爲什麼instanceof有時不會編譯,有時會返回false?
- 13. 爲什麼會出現在C#中沒有「WebElement」類硒?
- 14. 爲什麼這個PHP腳本會干擾我的CSS佈局?
- 15. 爲什麼不會Magento的佈局負荷
- 16. 爲什麼訪問嵌套類型會影響C++中的成員分辨率?
- 17. 爲什麼會有內存泄漏? (C)
- 18. Rails mongoid訂購embeds_many協會
- 19. 通過has_one協會訂購
- 20. C++爲什麼會拋出?
- 21. 什麼時候和爲什麼我會在C++中使用abs
- 22. CString'修剪':不是會員,爲什麼?
- 23. 爲什麼添加複選框到XML佈局會導致java.lang.ClassCastException?
- 24. 幫助理解爲什麼webview佈局不會加載頁面
- 25. 爲什麼jQuery有時會覆蓋window.onbeforeunload?
- 26. 爲什麼這有時會死機
- 27. 爲什麼getLocalhost()有時會凍結?
- 28. 爲什麼Hibernate有時會忽略FetchMode.JOIN?
- 29. 爲什麼會有這麼多的Rails記錄器,爲什麼會有鎖?
- 30. 爲什麼我會陷入僵局
C++ 11修訂此澄清,介入_repeated_訪問修飾符(無論何種原因,有人可能會包括那些)不妨礙佈局保證;只有當訪問級別通過_different_說明符更改時,纔會重複前一個。 – 2016-02-10 12:12:41