为什么我的结构的成员没有使用`{}`正确初始化?

我有以下代码:

#include <iostream> struct T { int a, b, c; }; int main() { T t = {0}; std::cout << ta << ',' << tb << ',' << tc << '\n'; } 

输出 :

 0,0,0 

经过多年的代码运行,在关键的生产环境中快乐地工作,发挥了至关重要的作用,项目的需求发生了变化,需要的输出是1,1,1

所以,我将{0}更改为{1}

 #include <iostream> struct T { int a, b, c; }; int main() { T t = {1}; std::cout << ta << ',' << tb << ',' << tc << '\n'; } 

输出 :

 1,0,0 

我预计1,1,1

为什么我的struct的成员没有被正确初始化?

当你写= {0}时,只显式初始化第一个成员 ; 其余的都是按照标准隐含地初始化的,所以乍一看你明确地初始化了所有的成员,而你写的是0但是你没有

你写0地方只影响第一个成员。 所以有一天,当你把它改成1以为它会改变所有的成员,你会有一个bug,就像这里。 这是误导/危险/愚蠢/脆弱的代码。

因此,如果没有相应的解释性评论, = {0}不会在我的团队中通过代码审查。 你原本应该写:

 T t = {}; 

而现在,要根据新的要求解决你的问题,你应该写:

 T t = {1,1,1}; 

或者,如果你不介意你的struct可能会失去POD性,给T一个构造函数。


正式的措辞

[C++11: 8.5.1/2]:按照8.5.4的规定,当初始化器列表初始化一个聚合器时,初始化器列表的元素将作为聚合器成员的初始化符,增加下标或会员订单。 每个成员都从相应的初始化子句复制初始化。 如果初始化子句是一个expression式,并且需要一个缩小的转换(8.5.4)来转换expression式,则该程序是格式不正确的。 [..]

[C++11: 8.5.1/6]:如果初始化子句的数量超过要初始化的成员或元素的数量,则初始化子列表格式不正确。

[C++11: 8.5.1/7]: 如果列表中的初始化子句less于聚合中的成员,则未初始化的每个成员都应该从空初始化列表 (8.5.4) 初始化,