I am learning C++ and I am a bit confused about the initialization of int variables.
This code (including the comments) is a copy/paste from Nawaz's answer in this topic Why does C++ require a user-provided default constructor to default-construct a const object?
struct POD
{
int i;
};
POD p1; //uninitialized - but don't worry we can assign some value later on!
p1.i = 10; //assign some value later on!
POD p2 = POD(); //initialized
For p2, I understand that the following is happening:
However, the comment says that p2 is initialized! Any explanation is welcome. Thanks.
For built-in types like int, the implicit default constructor does nothing (no initialization).
This is true but it is also not. Default initialization results in an unitialized object, while value initialization doesn't.
If no initializer is specified for an object, the object is default-initialized; if no initialization is performed, an object with automatic or dynamic storage duration has indeterminate value.
If you use int i;
this results in an uninitialized integer!
An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized.
If you use int i = int();
you have a value-initialized i
. Now, what is value-initialized?
To value-initialize an object of type T means:
- [...] (some options where T may be class or array type)
- otherwise, the object is zero-initialized.
Ok now we know that int i = int();
means having i=0
.
Since your struct is POD, value-initializing it means value-initializing all of its members.
You can have a shortcut on the general behaviour
int i1, i2 = int();
std::cout << i1 << std::endl;
std::cout << i2 << std::endl;
If the memory where i1 resides, isn't zero by any luck you can have the output will probably be
somevalue 0
[As @jogojapan mentioned correctly: Reading from i1
is undefined in first place, so don't do it. You'll most likely observe what I describe here but since the standard doesn't enforce compilers to behave this way i1
may be zero, or brake the expected result in any other strange way.]
Be aware of the following:
Note: Since () is not permitted by the syntax for initializer,
X a();is not the declaration of a value-initialized object of class X, but the declaration of a function taking no argument and returning an X.
Emphasis on standard quotes are mine.
If class type POD
has no user-defined constructor (as is the case in your example), then POD()
does not call default constructor. Instead the object is created without using any constructors at all. The compiler performs so called value-initialization of the temporary object. Value-initialization is a self-sufficient method of initialization, which does not necessarily use constructors. Instead, value-initialization of the entire object recursively performs value-initialization of all of its subobjects, one after another. For members of type int
value-initialization means zero-initialization.
This is why POD().i
is guaranteed to be zero. That zero was not placed there by any constructors. That zero was placed there by value-initialization.
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