c++ - 编译器如何确定位域结构的大小?

标签 c++ bit-fields

例如:

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_ 应该有相同的长度,但似乎不是。

为什么?

最佳答案

标准(the working draft 的 9.6)是这样说的:

specifies a bit-field; its length is set off from the bit-field name by a colon. The bit-field attribute is not part of the type of the class member. The constant-expression shall be an integral constant-expression with a value greater than or equal to zero. The constant-expression may be larger than the number of bits in the object representation ( 3.9 ) of the bit-field’s type; in such cases the extra bits are used as padding bits and do not participate in the value representation ( 3.9 ) of the bit-field. Allocation of bit-fields within a class object is implementation-defined. Alignment of bit-fields is implementation-defined. Bit-fields are packed into some addressable allocation unit. [ Note: bit-fields straddle allocation units on some machines and not on others. Bit-fields are assigned right-to-left on some machines, left-to-right on others. —end note]

(我的重点)

因此这将取决于您的编译器。在你的情况下似乎发生了什么 - 我会描述为相当正常的行为 - 它只是组合相同类型的位域然后将结构打包到 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 字节。

关于c++ - 编译器如何确定位域结构的大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18611253/

相关文章:

c++ - FLTK-不显示Mac iOS图像

c union 和位域

c++ - 如何去 GUI 一个复杂的 tanglewad C++/Qt4 应用程序?

c++ - 建立LLVM 10 C++工具链的问题

c - 为什么我从代码中带有位域的 C union 获得此输出?

c# - 在 C# 中,如何轻松地将枚举标志从一种类型映射到另一种类型?

c++ - visual studio 2015 (c++) 中的位域解析不正确

c - 强制转换时如何将连续位域转换为变量

c++ - 求模拟粒子轨迹的3D点和 vector 几何C++库

c++ - 调整大小以适应 QTableView 中的行和列非常慢