Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why std::array<int, 10> x is not zero-initialized but std::array<int, 10> x = std::array<int, 10>() seems to be?

I have just asked two questions about array and value initialization here and here. But with this code, I'm lost:

#include <iostream>
#include <iomanip>
#include <array>

template <class T, class U = decltype(std::declval<T>().at(0))>
inline U f1(const unsigned int i)
{T x; return x.at(i);}

template <class T, class U = decltype(std::declval<T>().at(0))>
inline U f2(const unsigned int i)
{T x = T(); return x.at(i);}

int main()
{
    static const unsigned int n = 10;
    static const unsigned int w = 20;
    for (unsigned int i = 0; i < n; ++i) {
        std::cout<<std::setw(w)<<i;
        std::cout<<std::setw(w)<<f1<std::array<int, n>>(i);
        std::cout<<std::setw(w)<<f2<std::array<int, n>>(i);
        std::cout<<std::setw(w)<<std::endl;
    }
    return 0;
}

As expected, f1 return arbitrary values as its values are not zero-initialized. But f2 seems to return exclusively zero values:

                   0                   0                   0
                   1                  61                   0
                   2                   0                   0
                   3                   0                   0
                   4           297887440                   0
                   5               32767                   0
                   6             4196848                   0
                   7                   0                   0
                   8           297887664                   0
                   9               32767                   0

Personally I thought that f2 will create an array with arbitrary values and copy/move it to x. But it does not seem to be the case.

So, I have two questions:

  • Why?
  • Do C++11 std::array<T, N> and C-style T[N] have the same behaviour in such a situation?
like image 519
Vincent Avatar asked Aug 18 '13 06:08

Vincent


People also ask

Are std :: array zero initialized?

std::array::array For elements of a class type this means that their default constructor is called. For elements of fundamental types, they are left uninitialized (unless the array object has static storage, in which case they are zero-initialized).

Is std :: array initialized?

std::array contains a built-in array, which can be initialized via an initializer list, which is what the inner set is. The outer set is for aggregate initialization.

What do you get when an array is not initialized in C++?

If an array is partially initialized, elements that are not initialized receive the value 0 of the appropriate type. The same applies to elements of arrays with static storage duration. (All file-scope variables and function-scope variables declared with the static keyword have static storage duration.)

Are arrays zero initialized in C++?

The array will be initialized to 0 if we provide the empty initializer list or just specify 0 in the initializer list.


1 Answers

Using {} or () as an initializer, with our without =, results in value initialization. For a type with an implicitly-declared constructor, value initialization implements zero initialization, which as its name suggests sets each primitive element to 0. This occurs before the constructor may be run, but in this case, the constructor does nothing.

Because the constructor does nothing (it is trivial), it is possible to see uninitialized data.

As for C-style arrays, the behavior is similar if you use = {} instead of = T(), as the latter is illegal. T() would ask for a temporary array object to be assigned to the named object, but arrays can't be assigned. = {} on the other hand assigns a braced-initializer-list to the array, and a braced-initializer-list is a special syntactic construct which is neither an expression nor an object.

like image 55
Potatoswatter Avatar answered Sep 20 '22 18:09

Potatoswatter