Default initialization of std::array?

C++11InitializationDefault ConstructorStdarray

C++11 Problem Overview


With C++11 std::array, do I have the guarantee that the syntax std::array<T, N> x; will default-initialize all the elements of the array ?

EDIT: if not, is there a syntax that will work on all arrays (including zero-sized arrays) to initialize all elements to their default value?

EDIT: on cppreference, the default constructor description says:

(constructor) (implicitly declared) (public member function)
default-constructs or copy-constructs every element of the array 

so the answer may be yes. But I would like to be sure of that according to the standard or future standard.

C++11 Solutions


Solution 1 - C++11

By definition, default initialization is the initialization that occurs when no other initialization is specified; the C++ language guarantees you that any object for which you do not provide an explicit initializer will be default initialized (C++11 §8.5/11). That includes objects of type std::array<T, N> and T[N].

Be aware that there are types for which default initialization has no effect and leaves the object's value indeterminate: any non-class, non-array type (§8.5/6). Consequently, a default-initialized array of objects with such types will have indeterminate value, e.g.:

int plain_int;
int c_style_array[13];
std::array<int, 13> cxx_style_array;

Both the c-style array and std::array are filled with integers of indeterminate value, just as plain_int has indeterminate value.

> Is there a syntax that will work on all arrays (including zero-sized arrays) to initialize all elements to their default value?

I'm guessing that when you say "to their default value" you really mean "initialize all elements to T{}". That's not default-initialization, it is value-initialization (8.5/7). You can request value initialization quite easily in C++11 by giving each declaration an empty initializer:

int plain_int{};
int c_style_array[13]{};
std::array<int, 13> cxx_style_array{};

Which will value-initialize all of the array elements in turn, resulting in plain_int, and all the members of both kinds of arrays, being initialized to zero.

Solution 2 - C++11

Default-initialization is a term from the Standard potentially meaning no initialization at all, so you probably mean zero-initialization.

The description at cppreference.com is actually a bit misleading. std::array is an aggregate class, and if the element type is primitive, it is POD: "plain old data," with semantics closely matching the C language. The implicitly-defined constructor of std::array< int, N > is a trivial one which does absolutely nothing.

Syntax like std::array< int, 3 >() or std::array< int, 3 > x{} which provide zeroed values do not do so by invoking a constructor. Getting zeroes is part of value-initialization, specified in C++11 §8.5/8:

> To value-initialize an object of type T means: > > — if T is a (possibly cv-qualified) class type without a user-provided or deleted default constructor, then the object is zero-initialized …, and if T has a non-trivial default constructor, the object is default-initialized;

std::array has no user-provided default constructor, so it gets zero-initialized. It has an implicitly-defined default constructor, but it is trivial, so it is never default-initialized. (But this doesn't make a difference since trivial initialization by definition has no effect at runtime.)

> if not, is there a syntax that will work on all arrays (including zero-sized arrays) to initialize all elements to their default value?

C-style arrays and std::array are both aggregates, and the way to completely zero-initialize any aggregate is with the syntax = {}. This works since C++98. Note that C-style arrays cannot have zero extent, and that sizeof (std::array< X, 0 >) is not zero.

Solution 3 - C++11

Both T x[N]; and std::array<T, N> x; default-initialize every element of the array.

For example, if T = std::string, every element will be an empty string. If T is a class without a default constructor, both will fail to compile. If T = int, every element will have indeterminate value (unless that declaration happens to be at namespace scope)

Solution 4 - C++11

C++11 std::array::fill is a good option for some cases.

Solution 5 - C++11

First of all, T x[N] does default initialize the elements, although default initialization of a scalar type T actually does nothing. The above also holds for std::array x. I think what you need is list initialization.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionVincentView Question on Stackoverflow
Solution 1 - C++11CaseyView Answer on Stackoverflow
Solution 2 - C++11PotatoswatterView Answer on Stackoverflow
Solution 3 - C++11CubbiView Answer on Stackoverflow
Solution 4 - C++11Assaf RamanView Answer on Stackoverflow
Solution 5 - C++11LingxiView Answer on Stackoverflow