在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));
特别是,我担心字符串数据。我想确保字符串的整个长度都包含零。它似乎可以在我当前的编译器中工作,但是规范的语言是否保证始终都是如此?
如果不是:是否有更好的方法将联合的全长初始化为零?
不,不能保证整个联合将被清零。保证只有第一个声明的工会成员,加上任何填充,才能归零(如下证明)。
因此,要确保并集对象的整个内存区域为零,您可以使用以下选项:
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] 删除。
我来说两句