Why std::array<int, 10> x is not zero-initialized but std::array<int, 10> x = std::array<int, 10>() seems to be?
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.
Vincent
Researcher, astrophysicist, computer scientist, programming language expert, software architect and C++ standardization committee member. LinkedIn: https://www.linkedin.com/in/vincent-reverdy
Updated on June 05, 2022Comments
-
Vincent almost 2 years
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. Butf2
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 tox
. But it does not seem to be the case.So, I have two questions:
- Why?
- Do C++11
std::array<T, N>
and C-styleT[N]
have the same behaviour in such a situation?