行为是否定义明确?
#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;
}
输出:
1
2
3
4
5
0
0
0
0
0
答案 0 :(得分:5)
是的,多余的元素被初始化为&#34;零&#34; (整数为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是一个(可能是cv-quali fi ed)类类型(第9条),带有用户提供的构造函数(12.1),那么 调用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是引用类型,则不执行初始化。