7
#include <stdint.h>
#include <stdio.h>

typedef union {
    uint64_t u[2];
    struct {
        uint64_t a:30;
        uint64_t b:30;
        uint64_t c:30;
        uint64_t d:30;
        uint64_t e:8;
    }x;
} mystruct;

int main()
{
    printf("Size %d\n", sizeof(mystruct));
}

我正在尝试在 64 位机器上编译它。预期的输出是 16,但我得到了 24。我知道这里发生了一些对齐,但我不确定为什么 struct x 正好是 16 个字节。有人可以解释一下吗。谢谢

4

3 回答 3

6

来自 C 标准:

(C99,6.7.2.1p10)“[...] 如果剩余空间不足,不适合的位字段是否被放入下一个单元或与相邻单元重叠是实现定义的。”

因此,在您的实现中,它们不会重叠:a并且b成员在一个单元中,c并且d在另一个单元中,并且e在另一个单元中:8 + 8 + 8 = 24.

于 2013-01-07T19:43:03.510 回答
6

对于 64 位机器,字段ab使用结构体中第一个 64 位值的 60 位,cd使用结构体中下一个 64 位值的 60 位,然后因为e是 8 位它不能放入该 64 位值剩余的 4 位,因此需要另一个 64 位值。因此 8x3 = 24 字节。

于 2013-01-07T19:44:11.697 回答
3

位字段的元素永远不会重叠两个内存“单元”(在您的情况下,内存单元是 64 位元素)。

除了位域实现依赖于编译器这一事实之外,您的位域结构很可能实际上以以下方式存储在内存中:

struct {
    uint64_t a:30;
    uint64_t b:30;
    uint64_t :4;
    uint64_t c:30;
    uint64_t d:30;
    uint64_t :4;
    uint64_t e:8;
    uint64_t :56;
}x;
于 2013-01-07T19:45:18.523 回答