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

时间:2015-05-14 23:35:40

标签: c++

在此代码中,C.B的所有100项都会初始化为零吗?

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

它似乎有效,但记忆可能事先是空的。

1 个答案:

答案 0 :(得分:5)

该行

A C = {0, 0}; 

执行value initialization A的{​​{3}}。根据标准,可以省略大括号的初始化:

8.5.1汇总[dcl.init.aggr] / 12

  

可以在初始化列表中省略大括号,如下所示。如果   初始化列表以左括号开头,然后是成功   逗号分隔的initializer-clauses列表初始化成员   分组;有更多的是错误的   初始化者 - 条款比成员。但是,如果是初始化列表   对于子聚合不是以左括号开始,而是仅以左括号开头   从列表中获取足够的初始化子句来初始化   分组成员;任何剩余的初始化条款都是   左边初始化聚合的下一个成员   current 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与完全支撑的效果相同   上面例子的初始化列表,

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

y的初始化程序以左括号开头,但y [0]的初始化程序不是,因此有三个元素   从列表中使用。同样接下来的三个是连续的   对于y [1]和y [2]。 - 结束例子]

下一步

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-initializers] 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
}