[英]How does the compiler determine the needed stack size for a function with compiler generated temporaries?
[英]How does compiler determine the size of a bitfield struct?
例如:
struct a {
uint32_t foreColor_ : 32;
uint32_t backColor_ : 32;
uint16_t lfHeight_ : 16;
uint16_t flags_: 4;
bool lfBold_: 1;
bool lfItalic_: 1;
bool lfUnderLine_: 1;
bool lfDashLine_: 1;
bool lfStrike_: 1;
bool lfSubscript_: 1;
bool lfSuperscript_: 1;
};
是16個字節但是
struct a {
uint32_t foreColor_ : 32;
uint32_t backColor_ : 32;
uint16_t lfHeight_ : 16;
uint8_t flags_: 4;
bool lfBold_: 1;
bool lfItalic_: 1;
bool lfUnderLine_: 1;
bool lfDashLine_: 1; //for ime
bool lfStrike_: 1;
bool lfSubscript_: 1;
bool lfSuperscript_: 1;
};
是12個字節長。
我認為flags_應該有相同的長度,但似乎沒有。
為什么?
標准( 工作草案的 9.6)說:
指定一個位域; 它的長度是通過冒號從位字段名稱中設置的。 bit-field屬性不是類成員類型的一部分。 常量表達式應為具有大於或等於零的值的整數常量表達式。 常量表達式可能大於位域類型的對象表示(3.9)中的位數; 在這種情況下,額外的比特用作填充比特,並且不參與比特字段的值表示(3.9)。 類對象中位域的分配是實現定義的。 位字段的對齊是實現定義的 。 比特字段被打包到一些可尋址的分配單元中。 [注意:位字段跨越某些機器上的分配單元而不是其他機器上的分配單元。 在某些機器上從右到左分配位字段,在其他機器上從左到右分配。 - 尾注]
(我的重點)
所以這取決於你的編譯器。 在您的情況下似乎正在發生的事情 - 我將其描述為相當正常的行為 - 是它只是組合相同類型的位域然后將結構打包到4字節邊界,所以在第一種情況下我們有:
struct a {
uint32_t foreColor_ : 32; // 4 bytes (total)
uint32_t backColor_ : 32; // 8 bytes
uint16_t lfHeight_ : 16; // 10 bytes
uint16_t flags_: 4; // 12 bytes
bool lfBold_: 1; // 13 bytes
bool lfItalic_: 1;
bool lfUnderLine_: 1;
bool lfDashLine_: 1;
bool lfStrike_: 1;
bool lfSubscript_: 1;
bool lfSuperscript_: 1; // still 13 bytes
};
然后填充到16個字節,在第二個字節中我們有:
struct a {
uint32_t foreColor_ : 32; // 4 bytes (total)
uint32_t backColor_ : 32; // 8 bytes
uint16_t lfHeight_ : 16; // 10 bytes
uint8_t flags_: 4; // 11 bytes
bool lfBold_: 1; // 12 bytes
bool lfItalic_: 1;
bool lfUnderLine_: 1;
bool lfDashLine_: 1;
bool lfStrike_: 1;
bool lfSubscript_: 1;
bool lfSuperscript_: 1; // still 12 bytes
};
它不需要填充,並保持12個字節。
它是特定於編譯器的,編譯器正在進行各種對齊以優化對字段的訪問。
如果你想(需要)依賴於對方。 (比如網絡頭處理)你需要使用#pragma push,pop。
或者__ attribute __(packed) - 這是一個GCC擴展。
struct {
...
} __attribute__(packed)
這將迫使編譯器壓縮它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.