是否允许位域的聚合初始化?

Is Aggregate Initialization of Bit-Fields Allowed?

我有一个包含位域的结构:

struct Foo {
    unsigned a : 16, b : 16;
};

而且我想知道我是否可以在它的位域上使用聚合初始化。例如:

struct Foo bar = {13, 42};

我注意到这个 does work in gcc 5.1 和 Visual Studio 2015。我只是想证明这是 C 和 C++ 的标准批准初始化。

从 C++14 [dcl.init.aggr] 我们有

An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).

所以Foo是一个符合聚合初始化条件的聚合。那么我们有

When an aggregate is initialized by an initializer list, as specified in 8.5.4, the elements of the initializer list are taken as initializers for the members of the aggregate, in increasing subscript or member order.[...]

Static data members and anonymous bit-fields are not considered members of the class for purposes of aggregate initialization.

因此在您的情况下,它们将被初始化,因为它们不是匿名的,并且它们将按照它们在 struct 中出现的顺序进行初始化。

从 C11 6.2.5(21) 我们有

Arithmetic types and pointer types are collectively called scalar types. Array and structure types are collectively called aggregate types.46)

所以在 C 中我们仍然在处理聚合。然后在 6.7.9(9) 中我们有

Except where explicitly stated otherwise, for the purposes of this subclause unnamed members of objects of structure and union type do not participate in initialization. Unnamed members of structure objects have indeterminate value even after initialization.

和 6.7.9(17)

Each brace-enclosed initializer list has an associated current object. When no designations are present, subobjects of the current object are initialized in order according to the type of the current object: array elements in increasing subscript order, structure members in declaration order, and the first named member of a union.148) In contrast, a designation causes the following initializer to begin initialization of the subobject described by the designator. Initialization then continues forward in order, beginning with the next subobject after that described by the designator.149)

因此我们的行为与 C++ 中的行为相同,其中匿名位字段未初始化,但由于它们已命名,因此将按照它们在 struct.

中出现的顺序进行初始化