c++ - 联盟初始化

标签 c++ initialization unions

管理 union 的未初始化字节的规则是什么? (假设一些已经初始化)

下面是一个 32 字节的 union ,我通过第一个成员只初始化了前 16 个字节。 似乎剩余的字节是零初始化的。这对我的用例来说很棒,但我想知道这背后的规则是什么 - 我期待垃圾。

#include <cstdint>
#include <iostream>

using namespace std;

union Blah {
   struct {
      int64_t a;
      int64_t b;
   };
   int64_t c[4];
}

int main()
{
   Blah b = {{ 1, 2 }}; // initialize first member, so only the first 16 bytes.

   // prints 1, 2, 0, 0 -- not 1, 2, <garbage>, <garbage>
   cout << b.c[0] << ", " << b.c[1] << ", " << b.c[2] << ", " << b.c[3] << '\n';

   return 0;
}

我使用 -O3 -Wall -Wextra -pedantic 在 GCC 4.7.2 上编译(最后一个需要为匿名结构命名)。希望这能让我免于走运。

我也尝试过在堆栈上覆盖两个具有两个不同作用域的变量,但 gcc 没有给它们相同的地址。

我也尝试过用另一个结构替换数组,在那种情况下会很重要,但它没有改变任何东西。

我无法从这里访问在线编译器,它们被我的工作阻止了。

最佳答案

C11 标准 6.2.6.1.7 中最相关的部分,虽然没有专门针对初始化:

When a value is stored in a member of an object of union type, the bytes of the object representation that do not correspond to that member but do correspond to other members take unspecified values.

第 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.

但并没有明确地出来说其他位没有被初始化。对于静态 union ,6.7.9.10 说:

the first named member is initialized (recursively) according to these rules, and any padding is initialized to zero bits;

因此第一个命名成员和任何填充位将被零初始化,但与 union 的其他(暗示更大)成员对应的位将未指定。

所以你不能指望那些被初始化为零的额外字节。

请注意,从技术上讲,即使您确实将 c 数组初始化为零,当您在 struct 中存储内容时,那些多余的位将再次变得未指定,您可以'指望它们仍然为零。有很多代码假设这是真的(例如,将 char 数组放在 union 中以访问各个字节),实际上它可能是这样,但标准并不能保证

关于c++ - 联盟初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26793250/

相关文章:

c - C 标准对两个相同类型的并集有什么看法

c - 如何在 C 中的结构内、 union 内使用结构?

c++ - 枚举结构和枚举类有什么区别?

c++ - 如何从句柄中获取事件的名称

c++ - RapidXML 打印头有未定义的方法

Java 构造函数与内联字段初始化

c++ - 为什么使用初始化方法而不是构造函数?

c - C 结构末尾有两个零长度数组成员

c++ - QT - 指向 QColor 的指针可以直接访问,但不能

c# - 数组属性初始化