【问题标题】:Size of a struct containing structs containing bitfields包含包含位域的结构的结构的大小
【发布时间】:2016-11-21 11:37:37
【问题描述】:

我有一个struct,看起来像下面这样:

typedef unsigned __int16 UINT16;
typedef unsigned __int64 UINT64;

struct Example {
    struct {
        UINT64 var1 : 5;
        UINT64 var2 : 2;
        UINT64 var3 : 29;
        UINT64 var4 : 23;
        UINT64      : 5;
    };
    struct {
        UINT16 var5 : 4;
        UINT16 var6 : 2;
        UINT16      : 10;
    };
};

我期待sizeof(struct Example) 返回10,但它返回了16。我不知道为什么会发生这种情况,如果能就此事提供任何意见,我将不胜感激。

【问题讨论】:

  • 可能对齐。如果数组中有两个Example 结构,它们可能需要在8 字节边界上对齐(因为UINT64)。为了确保第二个结构正确对齐,前一个结构最后需要有 6 个字节的填充。因此,大小为 16。
  • 您可以使用#pragma pack__attribute((packed)) 删除填充。但是在做出决定之前,您应该对结构包装进行一些研究。也就是说,在 SO 上搜索 [c] pragma pack[c] __attribute packed,并阅读一些关于包装的问答。
  • @chux 这真的取决于他使用的是 C 还是 C++。在 C++ 中很好。
  • @NathanOliver 没有注意到 C++ 标签。 LSNED。 Mutter:诅咒这些双语帖子。

标签: c struct


【解决方案1】:

这是由于字段对齐造成的。

第一个内部结构使用uint64_t 作为位域的基础类型,而第二个内部结构使用uint16_t 作为基础类型。

为了使整个结构正确对齐,它必须与最大“基础”内部字段所需的偏移量相同,在本例中为uint64_t,因此需要8个字节对齐。

如果没有这种对齐方式,如果创建了这种类型的数组,那么并非所有数组元素都将从 8 字节偏移量开始。因此在末尾添加了 6 个填充字节以确保正确对齐。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-08
    • 2013-04-05
    • 2011-11-22
    • 1970-01-01
    相关资源
    最近更新 更多