当初始化列表中没有更多元素时,是否初始化了数组的rest元素

yua*_*uan 1 c++ c++11

这种行为是否定义明确?

#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
    int a[10] = {1, 2, 3, 4, 5};
    for(const auto &i: a)
        cout << i << endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

1
2
3
4
5
0
0
0
0
0
Run Code Online (Sandbox Code Playgroud)

小智 5

是的,多余的元素被初始化为"零"(整数为0,浮点数为0.0,指向NULL).

更确切地说,C标准要求将它们初始化为好像它们具有static存储持续时间:

C99标准,第6.7.8.21段:

如果括号括起的列表中的初始值设定项少于聚合的元素或成员,或者用于初始化已知大小的数组的字符串文字中的字符数少于数组中的元素,则聚合的其余部分应为隐式初始化与具有静态存储持续时间的对象相同.

6.7.8.10:

如果未显式初始化具有自动存储持续时间的对象,则其值不确定.如果未显式初始化具有静态存储持续时间的对象,则:

- 如果它有指针类型,则将其初始化为空指针;

- 如果它有算术类型,则初始化为(正或无符号)零;

- 如果是聚合,则根据这些规则初始化(递归)每个成员;

- 如果它是一个联合,则根据这些规则初始化(递归)第一个命名成员.

该死的,这是C++.(除了@yuan之外没有人意识到这一点,谢谢!)

所以C++ 11中的第8.5.1.7节:

对值类型T的对象进行值初始化意味着:

- 如果T是具有用户提供的构造函数(12.1)的(可能是cv-quali fi ed)类类型(第9节),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化是错误的);

- 如果T是一个(可能是cv-quali fi ed)非联合类类型而没有用户提供的构造函数,那么该对象是零初始化的,如果T的隐式声明的默认构造函数是非平凡的,则调用该构造函数.

- 如果T是数组类型,则每个元素都是值初始化的;

- 否则,对象被零初始化.

8.5.1.5:

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

- 如果T是标量类型(3.9),则将对象设置为值0(零),作为整数常量表达式,转换为T; 103

- 如果T是(可能是cv-quali fi ed)非联合类类型,则每个非静态数据成员和每个基类子对象都是零初始化的,并且填充初始化为零位;

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

- 如果T是数组类型,则每个元素都是零初始化的;

- 如果T是引用类型,则不执行初始化.