位域如何与 C++ 中的位填充相互作用

How do bit fields interplay with bits padding in C++

查看本题的C版

当有填充位时,我有两个关于位域的问题。

假设我有一个结构定义为

struct T { 
    unsigned int x: 1; 
    unsigned int y: 1;
};

Struct T实际使用的只有两位。

问题 1:这两位是否始终是底层 unsigned int 的最低有效位?还是取决于平台?

问题2:那些未使用的30位是否总是初始化为0? C++ 标准对此有何规定?

Q1:通常是从低到高(即 x 是 1 << 0,y 是 1 << 1,等等)。

Q2:未使用位的值未定义。在某些 compilers/platforms 上,堆栈初始化变量 可能 首先设置为零( 可能 !!),但不要指望它!!堆分配的变量可以是任何东西,所以最好假设这些位是垃圾。使用埋在联合中的稍微不标准的匿名结构,你可以做这样的事情来确保位的值:

union T {
 unsigned intval;
 struct { 
   unsigned x : 1;
   unsigned y : 1;
 };
}; 

T foo;
foo.intval = 0;

Question 1: are these two bits always the least significant bits of the underlying unsigned int? Or it is platform dependent?

非常依赖平台。该标准甚至有一个注释只是为了说明多少:

[class.bit]

1 ...Allocation of bit-fields within a class object is implementation-defined. Alignment of bit-fields is implementation-defined. Bit-fields are packed into some addressable allocation unit. [ Note: Bit-fields straddle allocation units on some machines and not on others. Bit-fields are assigned right-to-left on some machines, left-to-right on others.  — end note ]

您不能对位域的对象布局做太多假设。

Question 2: Are those unused 30 bits always initialized to 0? What does the C++ standard say about it?

您的示例有一个简单的聚合,因此我们可以枚举可能的初始化。未指定初始值设定项...

T t;

... 将 default initialize 它,使成员具有不确定的价值。另一方面,如果您指定空括号...

T t{};

...对象将是 aggregate initialized,因此位字段将用 {} 本身初始化,并设置为零。但这仅适用于聚合的成员,即位域。没有指定填充位取什么值(如果有的话)。所以我们不能假设它们将被初始化为零。