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:
std::array<T, N>
and C-style T[N]
have the same behaviour in such a situation?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).
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.
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.)
The array will be initialized to 0 if we provide the empty initializer list or just specify 0 in the initializer list.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With