![](/img/trans.png)
[英]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.