将{0,0}初始化结构中的数组

Will {0, 0} initialize array in the struct?

本文关键字:结构 数组 初始化      更新时间:2023-10-16

在此代码中,C.B的100项是否全部初始化为0 ?

struct A { int B[100]; int D; };
A C = {0, 0};

似乎有效,但内存可能只是提前空了。

A C = {0, 0}; 

初始化聚合A的值。根据标准,对于聚合初始化,可以省略大括号:

8.5.1骨料(dcl.init.aggr)/12

大括号可以在初始化列表中省略,如下所示。如果初始化列表以左大括号开始,然后是后面的的初始化子句的逗号分隔列表初始化的成员subaggregate;有更多是错误的初始化子句不是成员。然而,如果是初始化列表对于子聚合不以左大括号开始,则仅从列表中获取足够的初始化子句来初始化子聚合的成员;任何剩余的初始化子句都是的聚合的下一个成员初始化当前子聚合是成员。

(例子:

 float y[4][3] = {
   { 1, 3, 5 },
   { 2, 4, 6 },
   { 3, 5, 7 }, }; 

是一个完全带括号的初始化:1、3、5初始化数组y[0]的第一行,即y[0][0];Y[0][1]和Y[0][2]。同样,下面两行初始化y[1]和y[2]。初始化式提前结束,因此y[3]的元素是的表达式显式初始化Form float(),也就是用0.0初始化。在下面例如,省略初始化列表中的大括号;然而,Initializer-list与完全带括号的list具有相同的效果上面示例的初始化器列表

 float y[4][3] = {
   1, 3, 5, 2, 4, 6, 3, 5, 7 }; 

y的初始化式以左大括号开始,但y[0]的初始化式没有左大括号,因此有三个元素从列表中使用。同样,接下来的三个是连续的对于y[1]和y[2]。- end示例]

接下来

8.5.1总量[dcl.init.aggr]/7

如果列表中的初始化子句比实际的少成员,则每个成员未显式初始化必须从大括号或相等初始化式或初始化式初始化(如果有)没有大括号或等号初始化项,来自空初始化项列表。

在您的示例中,这意味着第一个0被分配给B[0],第二个0被分配给B[1]。根据8.5.1/7,其余的元素都是值初始化的。

但是,为了清晰起见,您应该使用A C = {{0}, 0};,或者更好的

A C{}; // or A C = {};

唯一让我担心的是g++警告(-Wextra):

警告:成员'main()::A::D'缺少初始化式[- wmissing -field-initializer] A C {0,0};

但是根据我对上面标准的解释,你应该没问题,D应该已经初始化了。我甚至用一些位置new测试了它,结果如预期的那样

#include <iostream>
int main()
{
    struct A { int B[100]; int D;};
    A memory{};
    memory.D = 42; 
    std::cout << memory.D << std::endl;
    // let's place something an A at the location of memory
    A* foo = new (&memory) A{0,0}; 
    // line below outputs 0, so D is erased; not the case if A* foo = new (&memory) A; 
    std::cout << memory.D << std::endl; // outputs 0
}