我有以下型別,我的目標是優化 的大小Storage:
struct Inlined { int data[9]; }; // sizeof => 36
struct Allocated { int* data; size_t capacity }; // sizeof => 16
union Data { Inlined inlined; Allocated allocated; }; // sizeof => 40
struct Storage { // sizeof => 56
size_t size;
bool is_allocated;
Data data;
};
我了解大小和布局可能因編譯器和平臺而異。我的目標是至少在某些編譯器/平臺上獲得更緊湊的布局。
正如您在我的示例中看到的那樣,Data具有 4 個位元組的填充,因為Inlined并且Allocated具有不同的對齊方式并且Data是 8 位元組對齊的。我正在嘗試找到一種將布林值壓縮is_allocated到此填充中的方法。
到目前為止,我提出了以下結構,如果有人可以確認或否認這種型別的“安全”/“合法性”,我將不勝感激:
struct CompactStorage { // sizeof => 48
size_t size;
union {
struct {
bool is_allocated;
Inlined inlined;
};
struct {
bool copy_of_is_allocated;
Allocated allocated;
};
};
};
為了澄清起見,我的意思是我希望CompactStorage::is_allocated并CompactStorage::copy_of_is_allocated為相同的記憶體起別名。而且我希望,如果我寫入,CompactStorage::is_allocated那么它不會覆寫別名的位元組CompactStorage::allocated(反之亦然)。如果這不成立,那么我認為CompactStorage不安全,因為它不能用作Storage.
PS我知道位域,并且由于(經過驗證的)性能影響而故意不使用它們。
uj5u.com熱心網友回復:
這是非常明確的。來自[class.mem]
在具有結構型別 T1 的活動成員的標準布局聯合中,允許讀取結構型別 T2 的另一個聯合成員的非靜態資料成員 m,前提是 m 是 T1 和 T2 的公共初始序列的一部分;行為就像T1的相應成員被提名一樣。
常見的初始序列在哪里
兩種標準布局結構型別的共同初始序列是宣告順序中非靜態資料成員和位欄位的最長序列,從每個結構中的第一個此類物體開始,以便相應物體具有布局兼容型別[...]
這意味著您可以使用is_allocated和copy_of_is_allocated互換,因為結構是標準布局型別。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/525554.html
標籤:C 布局语言律师类型别名
