C++ C 样式零初始化 { 0 }.

c++ c-style zero-initialization { 0 }

本文关键字:初始化 样式 C++      更新时间:2023-10-16

https://en.cppreference.com/w/cpp/language/zero_initialization 表示在以下情况下发生零初始化:

int array[32] = {};

;但从来没有说过这个:

int array[32] = { 0 };

后者是否也在 c++ 中对整个数组进行零初始化,还是只初始化第一个元素?如果是这样,结构也是如此吗?

ISO/IEC N489 §9.4.1 声明

  • (5(对于非联合聚合,每个不是显式初始化元素的元素都按如下方式初始化:

    • (5.1(如果元素具有默认成员初始值设定项 (11.4(,则从该初始值设定项初始化元素。

    • (5.2( 否则,如果元素不是引用,则从空的初始值设定项列表 (9.4.4( 复制初始化该元素。

    • (5.3(否则,程序格式不正确。

§9.4.4 状态

  • (3.11(否则,如果初始值设定项列表没有元素,则对象是值初始化的。

标量的值初始化会导致其零初始化。因此,第二个仅显式初始化 0array[0]其余元素将初始化为零。


因此,以下代码

int array[4] = {13};

使用值初始化array

{13, 0, 0, 0}

后者是否也在 c++ 中对整个数组进行零初始化,还是只初始化第一个元素?

是的。

第一种风格是C++风格。

第二个是旧的C风格。

两个零都初始化整个数组元素(而不仅仅是第一个元素(。

如果是这样,结构也是如此吗?

是的。

...但从不说这件事

确实如此。这实际上是聚合初始化。

根据 cpp 首选项:

如果初始值设定项子句的数量小于成员和基数或初始值设定项列表

完全为空,则其余成员和基由其默认成员初始值设定项初始化(如果在类定义中提供(初始化,否则由空列表初始化,根据通常的列表初始化规则(该规则使用默认构造函数对非类类型和非聚合类执行值初始化, 和聚合的聚合初始化(。如果引用类型的成员是这些剩余成员之一,则程序格式不正确。

这保证了数组的其余元素使用空列表进行初始化。对于int(标量(,这会将其初始化为零。对于结构,如果结构不是聚合,这将执行值初始化,否则将执行聚合初始化。

使用 CppInsights 查看实际发生的情况:

这:

int main()
{
int array0[5];
int array1[5] = {};
int array2[5] = { 0 };
int array3[5] = { -1 };
int array4[5] = { 1, 2 };
}

相当于:

int main()
{
int array0[5];
int array1[5] = {0, 0, 0, 0, 0};
int array2[5] = {0, 0, 0, 0, 0};
int array3[5] = {-1, 0, 0, 0, 0};
int array4[5] = {1, 2, 0, 0, 0};
}

因此,int array2[5] = { v }显式初始化第一个元素v,默认初始化所有其他元素。