【问题标题】:Is Aggregate Initialization of Bit-Fields Allowed?是否允许位域的聚合初始化?
【发布时间】:2016-01-18 14:19:33
【问题描述】:

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

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

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

struct Foo bar = {13, 42};

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

【问题讨论】:

  • C 和 C++ 是不同的语言。选择一个。
  • @Olaf 我有一个 C 和 C++ 都使用的库。所以我不能选择一个,我当然希望两者的答案都是一样的。顺便说一句,gcc 对两者都适用,这是我在问题中的示例的 C 对应物:ideone.com/a3iVXw
  • @JonathanMee:“我有一个库” - 使用编译库的语言。 C 和 C++ 的语义有时存在细微差别。见上面我的一个 cmets。实际上,C 中的位域几乎没有用处。如果您必须(解)将字段打包为整数类型,只需使用位域即可;一个好的编译器会生成几乎相同的代码,但你会得到一个特定的布局。并且使用与实现相关的大小类型的位域总是一个坏主意。
  • @Olaf 我是说我正在编写的代码将用作两个独立项目中的库。一个是C++,一个是C。如果我需要把#ifdefs放进去我可以,但在这种情况下听起来没有必要。
  • 用 C 和 C++ 的相当小的通用子集编写库听起来是一种糟糕的方法。无论如何:你的项目,你的问题。

标签: c++ c initialization bit-fields aggregate-initialization


【解决方案1】:

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

聚合是一个数组或一个类(第 9 条),没有用户提供的构造函数(12.1),没有私有或受保护的非静态数据成员(第 11 条),没有基类(第 10 条),也没有虚拟函数 (10.3)。

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

当聚合被初始化列表初始化时,如 8.5.4 中所指定,初始化列表的元素被视为聚合成员的初始化,按递增的下标或成员顺序。[...]

出于聚合初始化的目的,静态数据成员和匿名位字段不被视为类的成员。

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

从 C11 6.2.5(21) 我们有

算术类型和指针类型统称为标量类型。数组和结构类型统称为聚合类型。46)

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

除非另有明确说明,就本子条款而言,结构和联合类型对象的未命名成员不参与初始化。即使在初始化之后,结构对象的未命名成员也具有不确定的值。

和 6.7.9(17)

每个用大括号括起来的初始化器列表都有一个关联的当前对象。没有时 指定存在时,当前对象的子对象根据当前对象的类型按顺序初始化:数组元素按递增下标顺序,结构成员按声明顺序,以及联合的第一个命名成员。148 sup>) 相反,指定会导致下面的初始化程序开始初始化指定符所描述的子对象。然后初始化按顺序继续向前,从指示符所描述的子对象之后的下一个子对象开始。149)

因此我们的行为与 C++ 中的行为相同,其中匿名位字段未初始化,但由于它们被命名,它们将按照它们在 struct 中出现的顺序进行初始化。

【讨论】:

  • 答案不完整。问题在于 C 和 C++。
  • @Olaf 我已经用 C 部分更新了答案。我正在收集相关标准,而我的 C 标准 pdf 比我的 C++ 更难搜索。
  • 最好提供标准的链接:port70.net/~nsz/c/c11/n1570.html
  • @Olaf 如果您想挑剔,那么没有办法提供标准链接,因为它们不公开。 (不过,至少C11和草案几乎一模一样,我发现唯一不同的是官方标准自带Cor 1:2012。)
  • @Lundin:虽然从技术上讲你是正确的,但正如你所提到的,草案和实际标准之间没有显着差异。事实上,cnages 是预料之中的。我只是想知道为什么它们出现在更正而不是最终标准本身中。无论如何,该链接主要是为了提供更易于搜索和链接的版本,因为 NathanOliver 提到他只有一个 pdf。由公共资金支付的标准(至少德国 DIN 是)仍然需要(相当多)钱,这真是太可惜了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-10
  • 1970-01-01
  • 2014-06-29
  • 2020-03-18
  • 1970-01-01
  • 2019-02-04
相关资源
最近更新 更多