在c ++中支持{}和{0}之间的初始化差异

时间:2016-12-06 22:40:46

标签: c++ c++11 compilation

几年前我读到使用{}和{0}来初始化POD在c ++中有一些细微的差别,其中一个可以在你的代码中引入悲观化。

D3D11_TEXTURE2D_DESC dsd = {};
D3D11_TEXTURE2D_DESC dsd2 = { 0 }:

虽然我知道{0}肯定是从c继承而且{}是c ++ 11中引入的东西,但两者都应该在编译期间被转换为同一个memset()调用:

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

然而,2个大括号初始化样式中的一个做了内存初始化未对齐的事情,是否有人关心哪种风格更好以及为什么?

2 个答案:

答案 0 :(得分:6)

您引用的语法称为aggregate initialization

  

如果初始化程序子句的数量小于成员数或初始化程序列表完全为空,则其余成员将进行值初始化

由于POD的值初始化与零初始化相同,因此您显示的两种语法之间没有区别。

甚至在C ++ 11之前就是这种情况 - 空的初始化列表不是它引入的东西。从C ++ 11开始,非POD也允许使用语法。聚合初始化现在是这个新列表初始化的特例。

答案 1 :(得分:-7)

两个版本都是“在C ++ 11中引入的东西”。 Brace初始化是“只是”一种调用构造函数的方法。例如。 D3D11_TEXTURE2D_DESC dsd = {};调用默认构造函数,而D3D11_TEXTURE2D_DESC dsd2 = { 0 };调用一个,可以使用const int作为唯一参数调用。除非你的一个构造函数这样做,否则它们都不会转换为类似于memset(&dsd, 0, sizeof(dsd));的任何东西。

如果你有隐式声明的默认构造函数,它只会为struct的每个元素调用默认构造函数。内置类型的默认构造函数不执行任何操作,因此内存不会设置为零。

对于那些没有定义构造函数且只有公共成员的struct个,以及一些可以归结为C struct的更多限制,你也得到aggregate initialization。这基本上是你期望来自C的。无论如何,D3D11_TEXTURE2D_DESC dsd2 = { 0 };不等同于memset(&dsd, 0, sizeof(dsd));,因为编译器可能出于任何原因向类添加填充,当然,还有字段的类型可能会在其构造函数中实现完全不同的东西。

好的,现在哪个更好,当然取决于你想要达到的目标。如果您正在处理C struct,我更喜欢第二个,因为您不会获得未初始化的值。但请忘记关于memset()等的任何假设。请改为查看构造函数。