在C++中定义"分配单元"?

Ben*_*ity 7 c++ memory-alignment language-lawyer bit-fields

在讨论位域时,C++ 17标准在第12.2.4节中多次使用术语"分配单元",但似乎没有定义该术语的含义.该标准还指出,"作为特殊情况,宽度为零的未命名位域指定分配单元边界处下一个位字段的对齐."

所以我对这些概念有两个问题,使用下面的代码作为例子:

  1. 该标准的术语"分配单位"是什么意思?

  2. 为未命名的位域指定的数据类型有何意义?

在第二个问题中,我的假设是数据类型意味着后面的位字段应该在该数据类型的下一个边界上对齐.

struct tag
{
   char X:3;
   unsigned int :0;   // start next bit-field on next unsigned int boundary?
   char Y:4;
   unsigned char :0;  // start next bit-field on next unsigned char boundary?
   long Z:32;
};
Run Code Online (Sandbox Code Playgroud)

P.W*_*P.W 1

我相信术语“分配单元”指的是位字段类型的大小。

关于位域的 CPP 参考声明:

可以强制大小为零的特殊未命名位字段分解填充。它指定下一个位字段从其分配单元的开头开始:

我修改了 CPP 参考中关于位字段的示例来说明这一点。

#include <iostream>
struct S1 {

    unsigned char b1 : 1;
    //unsigned char :0; // #1. start a new byte
    unsigned char b2 : 1;

};

struct S2 {

    unsigned int b1 : 10;
    //unsigned int :0; // #2. start a new int
    unsigned int b2 : 10;

};

int main()
{
    std::cout << sizeof(char) << '\n'; 
    std::cout << sizeof(int) << '\n'; 
    std::cout << sizeof(S1) << '\n'; // usually prints 1
    std::cout << sizeof(S2) << '\n'; // usually prints 4

}
Run Code Online (Sandbox Code Playgroud)

S1和的大小S2分别为 1 和 4,这也是char和的大小int。这是我们通常所期望的。
但是,如果我在上面的结构声明中取消注释行#1和,则和 的#2大小将分别为和 。这是您在问题中引用的陈述的结果:S1S228

作为一种特殊情况,宽度为零的未命名位字段指定下一个位字段在分配单元边界的对齐方式。”

现场演示