带布尔的C ++位域打包
收藏

我刚刚使用位域进行了测试,结果令人惊讶。

class test1 {
public:
    bool test_a:1;
    bool test_b:1;
    bool test_c:1;
    bool test_d:1;
    bool test_e:1;
    bool test_f:1;
    bool test_g:1;
    bool test_h:1;
};

class test2 {
public:
    int test_a:1;
    int test_b:1;
    int test_c:1;
    int test_d:1;
    int test_e:1;
    int test_f:1;
    int test_g:1;
    int test_h:1;
};

class test3 {
public:
    int test_a:1;
    bool test_b:1;
    int test_c:1;
    bool test_d:1;
    int test_e:1;
    bool test_f:1;
    int test_g:1;
    bool test_h:1;
};

结果是:-

sizeof(test1) = 1   // This is what I'd expect. 8 bits in a byte
sizeof(test2) = 4   // Reasonable. Maybe padded out to the size of an int.
sizeof(test3) = 16  // What???

这是您所期望的,还是编译器错误? (Codegear C ++ Builder 2007,btw ...)

最佳答案

您的编译器已将test3的所有成员安排在整数大小的边界上。一旦将块用于给定类型(整数位字段或布尔位字段),编译器将在下一个边界之前不再分配其他任何类型的位字段。

我怀疑这是一个错误。它可能与系统的基础体系结构有关。

编辑:

c ++编译器将按以下方式在内存中分配位域:相同类型的几个连续位域成员将按顺序分配。一旦需要分配一种新类型,它将与下一个逻辑存储块的开头对齐。下一个逻辑块将取决于您的处理器。某些处理器可以对齐8位边界,而其他处理器只能对齐16位边界。

在您的test3中,每个成员的类型都不同于之前的成员,因此内存分配将为8 *(系统上的最小逻辑块大小)。在您的情况下,最小块大小为两个字节(16位),因此test3的大小为8 * 2 = 16。

在可以分配8位块的系统上,我希望大小为8。

    公众号
    关注公众号订阅更多技术干货!