C++中"allocation unit"的定义是什么?

8
C++17标准在讨论位域时,在第12.2.4节中多次使用"allocation unit"这一术语,但似乎并没有定义这个术语的含义。该标准还声明:“作为特例,具有零宽度的未命名位域指定下一个位域在分配单元边界上对齐。”
因此,针对这些概念,我有两个问题,以下代码作为示例:
1. 标准中的“allocation unit”是什么意思? 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;
};

似乎与[4.4 intro.memory]/3中定义的“内存位置”有关,但我同意这很令人困惑。 - aschepler
1
我认为值得开一个编辑问题。 - Language Lawyer
2个回答

4
几乎所有位域的行为都是由具体实现定义的,因此您不能从标准中找到有关它们工作方式的详细信息。
术语“分配单元”是故意模糊的。它的定义实际上是通过暗示来完成的:
在类对象中分配位域是由具体实现定义的。位域的对齐方式也是由具体实现定义的。位域被打包到某个可寻址分配单元中。[强调添加][class.bit]/1
“分配单元”的含义由具体实现决定。唯一的要求是分配单元必须是“可寻址的”。这是唯一使用“可寻址的”词语的地方,因此您仍然需要自己理解。

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

}
S1S2 的大小分别为 1 和 4,这也是 charint 的大小。这是我们通常所期望的。
但是,如果我取消注释上面结构声明中的 #1#2 行,S1S2 的大小将分别为 28。这是你在问题中引用的语句的结果:

特殊情况下,宽度为零的未命名位域指定下一个位域在分配单元边界对齐。

在线演示


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接