C++11 空列表 union 的初始化 - 是否保证初始化 union 的全长?

标签 c++ c++11 unions list-initialization

在 C++11 中,我有以下 union :

union SomeData
{
    std::uint8_t Byte;
    std::uint16_t Word;
    std::uint32_t DWord;
    unsigned char String[128];
};

如果我这样初始化 union ;

SomeData data {};

是否保证 union 的全部内容将被“清零”?换一种方式;是 union 的空列表初始化器在功能上等同于将 union 内存设置为零?:

memset(&data, 0, sizeof(data));

我特别关心字符串数据。我想确保字符串的整个长度都包含零。它似乎适用于我当前的编译器,但规范的语言是否保证它始终为真?

如果不是:是否有更好的方法将 union 的全长初始化为零?

最佳答案

不,不能保证整个 union 会被清零。只有 union 的第一个声明的成员,加上任何填充,才能保证被归零(下面的证明)。

因此,为了确保 union 对象的整个内存区域都归零,您有以下选择:

  • 对成员进行排序,使最大的成员排在第一位,从而将那个清零。
  • 使用 std::memset 或等效功能。为了防止不小心忘记这一点,您当然可以给 SomeData 一个默认的构造函数来调用它。

引用 C++11:

8.5.4 [dcl.init.list]/3

List-initialization of an object or reference of type T is defined as follows:

  • If the initializer list has no elements and T is a class type with a default constructor, the object is value-initialized.

8.5 [dcl.init]/7

To value-initialize an object of type T means:

  • if T is a (possibly cv-qualified) class type (Clause 9) with a user-provided constructor (12.1), then the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
  • if T is a (possibly cv-qualified) non-union class type without a user-provided constructor, then the object is zero-initialized and, if T’s implicitly-declared default constructor is non-trivial, that constructor is called.
  • ...
  • otherwise, the object is zero-initialized.

8.5 [dcl.init]/5:

To zero-initialize an object or reference of type T means:

...

  • if T is a (possibly cv-qualified) union type, the object’s first non-static named data member is zero-initialized and padding is initialized to zero bits;

从这些引用中,您可以看到使用 {} 初始化 data 将导致对象被值初始化(因为 SomeData是具有默认构造函数的类类型)。

在没有用户提供的默认构造函数(SomeData 是)的情况下对 union 进行值初始化意味着对其进行零初始化。

最后,零初始化一个 union 意味着零初始化它的第一个非静态命名数据成员。

关于C++11 空列表 union 的初始化 - 是否保证初始化 union 的全长?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42534992/

相关文章:

c - 结构内部 union

c++ - 在类中初始化静态 union

c++ - GCC Profile Guided Optimization (PGO) 收集哪些信息以及哪些优化使用它?

c++ - std::move 为 "in-place operation"

包含 unsigned char 和 int 错误的 C++ 结构

c++ - 如何向 std::array 添加算术运算符?

c++ - 创建一个可能返回也可能不返回值的仿函数/lambda 的包装器

c++ - 为什么这个联盟显然持有不止一个值(value)?

c++ - "Invalid conversion"条件运算符错误

c++ - 如何在 C++ 中将 const int 设置为最大值?