Pri*_*alj 8 c c++ gcc struct bit-fields
参见在线示例: Ideone示例
struct {
union {
struct {
uint32_t messageID : 26;
uint8_t priority : 3;
} __attribute__ ((packed));
uint32_t rawID : 29;
} __attribute__ ((packed));
uint8_t canFlags : 3;
} __attribute__ ((packed)) idSpecial;
Run Code Online (Sandbox Code Playgroud)
为什么编译器会将结构的大小报告为5个字节而不是4个?它应该包含32位.
问题是__attribute__((packed))不执行按位打包.它只是保证struct成员之间没有填充.您可以尝试这个更简单的示例,其中size也报告为5:
typedef struct structTag {
struct {
uint32_t messageID : 26;
uint8_t priority : 3;
} __attribute__ ((packed));
uint8_t canFlags : 3;
} __attribute__ ((packed)) idSpecial;
Run Code Online (Sandbox Code Playgroud)
按位打包仅适用于位域成员.您需要将结构重新设计为结构与bitfields messageID/priority/canFlags的结合,以及带有bitfields rowID/canFlags的结构.换句话说,您需要有一些重复或使用访问器宏或成员函数.
这是因为内存对齐:编译器不会canFlags在一个字节的中间启动,它会在下一个字节的开头(可能是*)启动它.所以你的初始联合有四个字节,一个字节canFlags.
例如,如果你canFlags进入了联盟,那么它(可能是*)的大小为4:
typedef struct structTag {
union {
struct {
uint32_t messageID : 26; /* 26bit message id, 67108864 ids */
uint8_t priority : 3; /* priority: MUST BE 0 */
} __attribute__ ((packed));
uint32_t rawID : 29;
uint8_t canFlags : 3; /* <==== Moved */
} __attribute__ ((packed));
} __attribute__ ((packed)) idSpecial;
Run Code Online (Sandbox Code Playgroud)
有关ideone的更新示例.显然,这种具体的变化可能不是你想要的; 我只是在证明问题是在字节边界上开始一个新字段.
*"可能"因为最终取决于编译器.
| 归档时间: |
|
| 查看次数: |
1103 次 |
| 最近记录: |