简体   繁体   English

{0,0}会在结构中初始化数组吗?

[英]Will {0, 0} initialize array in the struct?

In this code, will all 100 items of CB be initialized to zero? 在此代码中,是否会将所有100个CB项目初始化为零?

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

It seems to work, but memory could have just been empty in advance. 它似乎可以正常工作,但是内存可能事先已空了。

The line 线

A C = {0, 0}; 

Performs value initialization of the aggregate A . 执行集合 A 值初始化 According to the standard, the braces can be omitted for aggregate initialization: 根据标准,括号可以省略以进行聚合初始化:

8.5.1 Aggregates[dcl.init.aggr]/12 8.5.1聚合[dcl.init.aggr] / 12

Braces can be elided in an initializer-list as follows. 可以将括号括在初始化列表中,如下所示。 If the initializer-list begins with a left brace, then the succeeding comma-separated list of initializer-clauses initializes the members of a subaggregate; 如果初始化列表以左花括号开头,则后续的逗号分隔列表的初始化子句将初始化子聚合的成员;否则,将初始化子聚合的成员。 it is erroneous for there to be more initializer-clauses than members. 初始化子句多于成员是错误的。 If, however, the initializer-list for a sub- aggregate does not begin with a left brace, then only enough initializer-clauses from the list are taken to initialize the members of the subaggregate; 但是,如果子聚合的初始值设定项列表不是以左大括号开头,则仅从列表中获取足够的初始化子句来初始化子聚合的成员;否则,请执行以下步骤。 any remaining initializer-clauses are left to initialize the next member of the aggregate of which the current subaggregate is a member. 剩下的所有初始化程序子句都将初始化当前子聚合所属的聚合的下一个成员。

[Example: [例:

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

is a completely-braced initialization: 1, 3, and 5 initialize the first row of the array y[0], namely y[0][0], y[0][1], and y[0][2]. 是完全支撑的初始化:1、3和5初始化数组y [0]的第一行,即y [0] [0],y [0] [1]和y [0] [2] 。 Likewise the next two lines initialize y[1] and y[2]. 同样,接下来的两行初始化y [1]和y [2]。 The initializer ends early and therefore y[3]'s elements are initialized as if explicitly initialized with an expression of the form float(), that is, are initialized with 0.0. 初始化程序提前结束,因此y [3]的元素被初始化,就好像使用float()形式的表达式进行了显式初始化一样,即使用0.0进行了初始化。 In the following example, braces in the initializer-list are elided; 在下面的示例中,省略了initializer-list中的花括号; however the initializer-list has the same effect as the completely-braced initializer-list of the above example, 但是,initializer-list与上述示例的完全支撑的initializer-list具有相同的效果,

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

The initializer for y begins with a left brace, but the one for y[0] does not, therefore three elements from the list are used. y的初始值设定项以左大括号开头,而y [0]的初始设定项则没有,因此使用列表中的三个元素。 Likewise the next three are taken successively for y[1] and y[2]. 同样,接下来的三个分别用于y [1]和y [2]。 — end example ] —结束示例]

Next 下一个

8.5.1 Aggregates[dcl.init.aggr]/7 8.5.1聚合[dcl.init.aggr] / 7

If there are fewer initializer-clauses in the list than there are members in the aggregate, then each member not explicitly initialized shall be initialized from its brace-or-equal-initializer or, if there is no brace-or-equal- initializer, from an empty initializer list. 如果列表中的初始化程序子句少于聚合中的成员,则每个未显式初始化的成员都应从其花括号或相等初始化器进行初始化,或者,如果没有花括号或相等初始化器,则从一个空的初始化列表中。

In your case, this mean that the first 0 is assigned to B[0] and the second 0 is assigned to B[1] . 在您的情况下,这意味着第一个0分配给B[0] ,第二个0分配给B[1] According then to 8.5.1/7 , the rest of the elements are value-initialized. 然后根据8.5.1 / 7 ,其余元素将进行值初始化。

However, for clarity in this case, you should use AC = {{0}, 0}; 但是,在这种情况下,为清楚起见,应使用AC = {{0}, 0}; , or, better , 或更好

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

The only thing that worries me a bit is the g++ warning ( -Wextra ): 唯一让我担心的是g ++警告( -Wextra ):

warning: missing initializer for member 'main()::A::D' [-Wmissing-field-initializers] AC {0,0}; 警告:缺少成员'main():: A :: D'的初始化程序[-Wmissing-field-initializers] AC {0,0};

But according to my interpretation of the standard above, you should be OK and D should have been initialized. 但是根据我对上述标准的解释,您应该可以,并且D应该已经初始化。 I even tested it with some placement new , and the result is as expected 我什至用一些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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM