Reputation: 1863
I'm confused about the default initialization of the class data members. Here is the sample code.
#include <iostream>
#include <vector>
class A {
public:
int i;
A() {}
};
A a1;
A aa1[3];
std::vector<A> av1(3);
int main()
{
A a2;
A aa2[3];
std::vector<A> av2(3);
std::cout << a1.i << " " << a2.i << std::endl; // 0 undefined
std::cout << aa1[0].i << " " << aa2[0].i << std::endl; // 0 undefined
std::cout << av1[0].i << " " << av2[0].i << std::endl; // undefined undefined
}
In the code above, only a1.i
and aa1[0~2].i
are initialized to 0, while others are uninitialized. I don't know why that happened.
To be specific, what I already know from C++ Primer is that:
The process of initialization is:
a1
and a2
are default initialized.aa1
and aa2
are default initialized.av1
and av2
are value initialized.The process of default initialize is:
The process of value initialize is:
So when the ctor A::A()
is called, how is the data member A::i
initialized (I guess it is default initialized)? And why are only a1.i
and aa1[0~2].i
initialized to 0, while others are uninitialized?
Upvotes: 20
Views: 21731
Reputation: 81
The initialization of an object of class type is controlled by the class, and this process is done recursively. Take your sample code for example, the initialization of i
is controlled by A
. Since no constructor is provided, the synthesized default constructor will be used. And since no in-class initializers are provided, every member of A
is default initialized, again, the default initialization rule is queried. The built-in type i
will be left uninitialized. If A
contains a member s
of type string
, then the default initialization of s
is controlled by the string
class (the recursive rule takes place). In this case, s
will be initialized to an empty string.
Upvotes: 1
Reputation: 62777
Global (both static and exported) variables are zero-initialized (in practice, on usual platforms, they are in memory are which is filled with zeros at program start), if they are not explicitly initialized and don't have a constructor.
Items of vector are default-initialized, when you use the constructor you are using in your code.
For a vector class object, both mean a constructor call. But for integers, first means initialized to zero, while latter means initialized with indeterminate value. So the plain int variables in your code are zero-initialized, but the ints in the vector are default initialized.
Some links for reference:
Upvotes: 2
Reputation: 32894
when the ctor A::A() is called, how the data member A::i initialized
If no initializer is provided, the rules of default initialization apply. Your constructor does no initialization of A::i
so it's left uninitialized; it's value is indeterminate. No doubt about that. Excerpt from the documentation on default initialization:
If T is a class type, the constructors are considered and subjected to overload resolution against the empty argument list. The constructor selected (which is one of the default constructors) is called to provide the initial value for the new object.
why only a1.i and aa1[0~2].i are initialized to 0, while others are uninitialized?
The global data memory is initialized to zero i.e. the whole section is zeroed out and so you see global A::i
s initialized to 0
. Note that the constructor would not be doing this. Excerpt from the documentation:
Static initialization
[...]
2) For all other non-local static and thread-local variables, Zero initialization takes place. In practice, variables that are going to be zero-initialized are placed in the .bss segment of the program image, which occupies no space on disk, and is zeroed out by the OS when loading the program.
However, for the vector
, the vector
itself is in the non-local static memory while its elements are allocated in free store (heap) and hence their members are uninitialized too.
Upvotes: 11
Reputation: 32732
You declare a constructor for A
, so there is no default initialization of i
; that's your responsibility in the constructor. The global variables get initial values of 0 because they're global. All globals are initialized to 0 if they aren't given an initial value by some means.
The local variables and vectors get random data because that's what's in the memory on the stack (for locals) or heap (for the allocated memory that the vector uses) that is being used by those A
instances.
Upvotes: 1