C++ struct with char arrays initialize to zero in unusual way
Asked Answered
C

1

6

Came across a non-common bit of c++ initialization code that seems to work fine with the following...

struct sfoobar { char bar[10]; char foo[10]; };
...
sfoobar x { 0 };

Is this an acceptable method for initializing these char arrays to zero?

Cenozoic answered 24/4, 2018 at 3:0 Comment(5)
non-common it is actually quite common.Bidarka
Yes, that is an acceptable way to do it.Ethic
sfoobar x { }; would be a preferred pattern, because it still works even if 0 is not a correct initializer for the first member. Compare with struct qux { std::string bar; char foo[10]; }; , then qux x{0}; causes undefined behaviourLeanora
@Leanora Could you please elaborate why qux x{0}; causes UB? Why wouldn't this simply generate a compile error instead? (If std::string doesn't support such initialization.)Scrunch
@Scrunch std::string has a constructor taking char const * (UB if null pointer passed) and 0 can be implicitly converted to null pointerLeanora
L
8

This is valid in C++. As the effect sfoobar x { 0 }; would initialize all the elements of x.bar and x.foo to 0.

According to the rule of aggregate initialization, the braces for nested initializer lists could be omitted,

the braces around the nested initializer lists may be elided (omitted), in which case as many initializer clauses as necessary are used to initialize every member or element of the corresponding subaggregate, and the subsequent initializer clauses are used to initialize the following members of the object.

then sfoobar x { 0 }; means initializing the 1st element of x.bar to 0, and

If the number of initializer clauses is less than the number of members and bases (since C++17) or initializer list is completely empty, the remaining members and bases (since C++17) are initialized by their default initializers, if provided in the class definition, and otherwise (since C++14) by empty lists, in accordance with the usual list-initialization rules (which performs value-initialization for non-class types and non-aggregate classes with default constructors, and aggregate initialization for aggregates).

So all the remaining elements, including the 2nd to 10th elements of x.bar and all the elements of x.foo would be value-initialized to 0 too.

Lector answered 24/4, 2018 at 3:20 Comment(4)
question, is value initialization and zero initialization the same for char arrays?Rostand
@codekaizer Yes, for non-class types value initialization leads to zero initialization. For this case, the flow would be aggregate initialization on char array then value initialization on elements (i.e. chars) then zero initialization on elements (i.e. chars).Lector
So if I write sfoobar x { 1 }; instead, then the first element of x.bar is initialized to one, and all other elements of x.bar and all elements of x.foo are initialized to zero? And if I just write sfoobar x, then the values of the elements of x.bar and x.foo are undetermined?Kyat
@M.Winter Yes, exactly.Lector

© 2022 - 2024 — McMap. All rights reserved.