c++ - Why compilers put zeros into arrays while they do not have to? -
i'm trying understand when compilers should value initialize arrays , when should default initialize it. i'm trying 2 options: 1 raw array, array aggregated in struct:
const int n = 1000; struct { uint32_t arr[n]; a() = default; }; void print(uint32_t* arr, const std::string& message) { std::cout << message << ": " << (std::count(arr, arr + n, 0) == n ? "all zeros" : "garbage") << std::endl; } int main() { uint32_t arrdefault[n]; print(arrdefault, "automatic array, default initialization"); uint32_t arrvalue[n] = {}; print(arrvalue, "automatic array, value initialization"); uint32_t* parrdefault = new uint32_t[n]; print(parrdefault, " dynamic array, default initialization"); uint32_t* parrvalue = new uint32_t[n](); print(parrvalue, " dynamic array, value initialization"); structdefault; print(structdefault.arr, "automatic struct, default initialization"); structvalue{}; print(structvalue.arr, "automatic struct, value initialization"); a* pstructdefault = new a; print(pstructdefault->arr, " dynamic struct, default initialization"); a* psstructvalue = new a(); print(psstructvalue->arr, " dynamic struct, value initialization"); }
automatic array, default initialization: garbage automatic array, value initialization: zeros dynamic array, default initialization: garbage dynamic array, value initialization: zeros automatic struct, default initialization: zeros automatic struct, value initialization: zeros dynamic struct, default initialization: garbage dynamic struct, value initialization: zeros
output gcc different in first line, puts "all zeros".
from point of view wrong, , expect is:
automatic array, default initialization: garbage automatic array, value initialization: zeros dynamic array, default initialization: garbage dynamic array, value initialization: zeros automatic struct, default initialization: garbage automatic struct, value initialization: garbage dynamic struct, default initialization: garbage dynamic struct, value initialization: garbage
i.e. output ok raw arrays (except gcc): have garbage default , zeros value. great. struct expect have garbage time. default initialization:
default initialization performed in 3 situations:
- ...
- ...
- when base class or non-static data member not mentioned in constructor initializer list , constructor called.
the effects of default initialization are:
- if t non-pod (until c++11) class type, ...
- if t array type, every element of array default-initialized;
- otherwise, nothing done: objects automatic storage duration (and subobjects) initialized indeterminate values.
in example have non-static data member not mentioned in constructor initializer list, array of pod type. expect left indeterminate values, no matter how struct constructed.
my questions are:
- why compilers violate that? mean, why put zeros when not have to, wasting runtime? wrong in readings?
- how can enforce such behavior make sure not waste runtime populating arrays zeros?
- why gcc performs value initialization automatic array?
a structvalue{};
aggregate initialization, 0 guaranteed.
as a
has no user provided constructor because explicitly defaulted constructors not count such, same applies value initialization in a* psstructvalue = new a();
.
for default initialization cases: reading uninitialized variables ub, , undefined behavior undefined. compiler can whatever wants. showing 0 legal crashing. maybe there 0 in memory read chance. maybe compilers felt 0 initializing. both equally fine standard's point of view.
that being said, have better chance of seeing garbage when testing release / optimized builds. debug builds tend stuff diagnosing problems, including doing initialization.
(for record: gcc , clang -o3 appear no unnecessary initialization on linux system @ first glance. nevertheless, got "all zeroes" every case. appears chance.)
Comments
Post a Comment