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

BTownTKD

在C ++ 11中,我具有以下联合:

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

如果我这样初始化联合;

SomeData data {};

是否保证工会全部内容都将被“归零”?换一种方式; 联合的空列表初始化函数在功能上等同于将联合设置为零?

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

特别是,我担心字符串数据。我想确保字符串的整个长度都包含零。它似乎可以在我当前的编译器中工作,但是规范的语言是否保证始终都是如此?

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

Angew不再为SO感到骄傲

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

因此,要确保并集对象的整个内存区域为零,您可以使用以下选项:

  • 对成员进行排序,以使最大的成员排在第一位,从而使该成员归零。
  • 使用std::memset或等效功能。为了防止意外忘记,您当然可以提供SomeData一个默认的构造函数来调用它。

引用C ++ 11:

8.5.4 [dcl.init.list] / 3

对象或类型引用的列表初始化T定义如下:

  • 如果初始化器列表没有元素,并且T是带有默认构造函数的类类型,则该对象将被值初始化。

8.5 [dcl.init] / 7

值初始化的类型的对象T是指:

  • 如果T是具有用户提供的构造函数(12.1)的(可能是cv限定的)类类型(第9条),则T调用的默认构造函数(如果T没有可访问的默认构造函数,则初始化格式不正确);
  • 如果T是没有用户提供的构造函数的(可能是cv限定的)非工会类类型,则该对象将初始化为零,并且如果T隐式声明的默认构造函数非平凡,则将调用该构造函数。
  • ...
  • 否则,将对象初始化为零。

8.5 [dcl.init] / 5:

对对象或类型的引用进行零初始化T意味着:

...

  • 如果T是(可能是cv限定的)联合类型,则对象的第一个非静态命名数据成员将初始化为零,并且填充将初始化为零位;

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

没有用户提供的默认构造函数(即SomeData)的值初始化联合意味着将其零初始化。

最后,对联合进行零初始化是指对其第一个非静态命名数据成员进行零初始化。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章