Does int a = int(); necessarily give me a zero?
How about if int is replaced by char, double, bool or pointer type?
Where is this specified in the language standard, please?
Does int a = int(); necessarily give me a zero?
Yes, the standard guarantees that it gives you zero.
This is known as Value Initialization. For the type int, Value Initialization basically ends up being an Zero Initialization.
Where is this specified in the language standard, please?
The rules are clearly specified in the standard in section 8.5.
I will quote the relevant ones to the Q here:
C++03: 8.5 Initializers
Para 7:
An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized.
Value Initialization & Zero Initialization are defined in 8.5 Para 5 as:
To value-initialize an object of type T means:
— if T is a class type (clause 9) with a user-declared constructor (12.1), then the default
constructor for T is called (and the initialization is ill-formed if T has no accessible
default constructor);
— if T is a non-union class type without a user-declared constructor, then every non-static
data member and base-class component of T is value-initialized;
— if T is an array type, then each element is value-initialized;
— otherwise, the object is zero-initialized
To zero-initialize an object of type T means:
— if T is a scalar type (3.9), the object is set to the value of 0 (zero) converted to T;
— if T is a non-union class type, each nonstatic data member and each base-class subobject
is zero-initialized;
— if T is a union type, the object’s first named data member is zero-initialized;
— if T is an array type, each element is zero-initialized;
— if T is a reference type, no initialization is performed.
Note: The bold texts are emphasized by me.
Yes, any built-in type is always initialized to zero when default-initialized. Keep in mind that in most scenarios a built-in type is not default initialized so this won't necessarily print out 0:
int i;
std::cout << i << "\n";
Related
Consider following program:
#include <iostream>
struct Test
{
int a;
};
int main()
{
Test t=Test();
std::cout<<t.a<<'\n';
}
Test t=Test(); value initializes a temporary & copy initializes it. (most compilers optimize out the copy operation (Source: value initialization)). But value initialization is introduced by C++03. What happens in C++98 when Test t=Test(); is executed? Is it guaranteed that I will get 0 as an output (value of t.a in this case) on any C++98 compiler? . Is it default initialization being performed in C++98?
C++ standard (1998)
[dcl.fct.def]
7 An object whose initializer is an empty set of parentheses, i.e., (), shall be default-initialized.
[dcl.init]
5 To zero-initialize storage for an object of type T means:
— if T is a scalar type (3.9), the storage is set to the value of 0 (zero) converted to T;
— if T is a non-union class type, the storage for each nonstatic data member and each base-class subobject is zero-initialized;
— if T is a union type, the storage for its first data member 89) is zero-initialized;
— if T is an array type, the storage for each element is zero-initialized;
— if T is a reference type, no initialization is performed.
To default-initialize an object of type T means:
— if T is a non-POD class type (clause 9), the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
— if T is an array type, each element is default-initialized;
— otherwise, the storage for the object is zero-initialized.
It appears that the temporary is default initialized, which means zero initialization for a POD type (which Test is) and therefore t.a == 0 is guaranteed.
Since C++03 this is value initialization and same guarantee remains.
It appears that the addition of value initialization and re-definition of default initialization in C++03, was to allow not zero-initializing scalars and POD types (in some contexts).
This question already has answers here:
Does the default constructor of std::pair<> set basic types (int, etc) to zero?
(3 answers)
Closed 9 years ago.
#include <iostream>
#include <string>
int main() {
std::pair<std::string, int> s;
std::cout << s.second << std::endl;
}
In this example s.second is 0 though it is not initialized. Can you provide a link to C++ standard where is defined why is it 0. I know it is because s.second is initialized by int(), but cant found the line in standard where is stated that int() is 0.
It's
8.5 Initializers [dcl.init]
10) An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized.
and
7) To value-initialize an object of type T means:
— if T is a (possibly cv-qualified) class type (Clause 9) with a user-provided constructor (12.1), then the
default constructor for T is called (and the initialization is ill-formed if T has no accessible default
constructor);
— if T is a (possibly cv-qualified) non-union class type without a user-provided constructor, then the object
is zero-initialized and, if T’s implicitly-declared default constructor is non-trivial, that constructor is
called.
— if T is an array type, then each element is value-initialized;
— otherwise, the object is zero-initialized.
and I guess
5) To zero-initialize an object or reference of type T means:
— if T is a scalar type (3.9), the object is set to the value 0 (zero), taken as an integral constant expression,
converted to T; [...]
I know it is because s.second is initialized by int(), but cant found the line in standard where is stated that int() is 0.
Here is the path you have to follow in the C++11 Standard - this answer uses Draft n3485 as a reference, which is more recent than the current official Standard.
Per Paragraph 8.5/11 of the C++11 Standard:
An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized. [...]
Moreover, per Paragraph 8.5/8 of the C++11 Standard:
To value-initialize an object of type T means:
— if T is a (possibly cv-qualified) class type (Clause 9) with either no default constructor (12.1) or a
default constructor that is user-provided or deleted, then the object is default-initialized;
— if T is a (possibly cv-qualified) non-union class type without a user-provided or deleted default constructor,
then the object is zero-initialized and, if T has a non-trivial default constructor, default-initialized;
— if T is an array type, then each element is value-initialized;
— otherwise, the object is zero-initialized.
Finally (although this is quite intuitive), per Paragraph 8.5/6:
To zero-initialize an object or reference of type T means:
— if T is a scalar type (3.9), the object is set to the value 0 (zero), taken as an integral constant expression, converted to T;
— [...]
I know it is because s.second is initialized by int()
The standard doesn't actually say that second is initialized with int(). It just gives the effect of creating a std::pair with the default constructor as (§20.3.2):
Effects: Value-initializes first and second.
Value-initialization is defined as (§8.5):
To value-initialize an object of type T means:
if T is a (possibly cv-qualified) class type (Clause 9) [...]
if T is a (possibly cv-qualified) non-union class type [...]
if T is an array type, [...]
otherwise, the object is zero-initialized.
Whcih results in second being zero-initialized because it is an int (§8.5):
To zero-initialize an object or reference of type T means:
if T is a scalar type (3.9), the object is set to the value 0 (zero), taken as an integral constant expression, converted to T;
[...]
I only just learned yesterday that specifying parameters to initializer list items is optional. However, what are the rules for what happens in this case?
In the below example, will ptr be initialized to 0, toggle to false, and Bar default-constructed? I guess this question is sort of redundant, because there would be little point in initializer lists if unspecified argument values == undefined behavior.
Could I also be pointed to the section of the C++ standard that states the behavior in the case of initializer list items not being given arguments?
class Bar
{
Bar() { }
};
class SomeClass;
class AnotherClass
{
public:
SomeClass *ptr;
bool toggle;
Bar bar;
AnotherClass() : ptr(), toggle(), bar() { }
// as opposed to...
// AnotherClass() : ptr(NULL), toggle(false), bar(Bar()) { }
};
Yes, the members will be initialized to zero and a default-constructed object respectively.
The C++ 11 standard specifies this behavior in 12.6.2/7:
The expression-list or braced-init-list in a mem-initializer is used
to initialize the designated subobject (or, in the case of a
delegating constructor, the complete class object) according to the
initialization rules of 8.5 for direct-initialization.
In turn, 8.5/10 reads:
An object whose initializer is an empty set of parentheses, i.e., (),
shall be value-initialized.
Paragraph 8.5/7 defines value-initialized:
To value-initialize an object of type T means:
if T is a (possibly cv-qualified) class type (Clause 9) with a user-provided constructor
(12.1), then the default constructor for T is called (and the
initialization is ill-formed if T has no accessible default
constructor);
if T is a (possibly cv-qualified) non-union class type
without a user-provided constructor, then the object is
zero-initialized and, if T’s implicitly-declared default constructor
is non-trivial, that constructor is called.
if T is an array type,
then each element is value-initialized;
otherwise, the object is
zero-initialized.
And finally, 8.5/5 defines zero-initialized:
To zero-initialize an object or reference of type T means:
if T is a
scalar type (3.9), the object is set to the value 0 (zero), taken as
an integral constant expression, converted to T;
if T is a
(possibly cv-qualified) non-union class type, each non-static data
member and each base-class subobject is zero-initialized and padding
is initialized to zero bits;
if T is a (possibly cv-qualified) union
type, the object’s first non-static named data member is zero-
initialized and padding is initialized to zero bits;
if T is an
array type, each element is zero-initialized;
if T is a reference
type, no initialization is performed.
In the below example, will ptr be initialized to 0, toggle to false, and Bar default-constructed?
Yes. If a member initialiser appears in the initialiser list with empty parentheses, then that member is value initialised. This means that numerical types will be initialised to zero, pointers to null, and classes with default constructors using that constructor.
If you don't include the member in the initialiser list at all, then it will instead be default initialised; in that case. numerical and pointer types will be left uninitialised.
Could I also be pointed to the section of the C++ standard that states the behavior in the case of initializer list items not being given arguments?
C++11 12.6.2/7 specifies that the rules are the same as for direct initialisation.
C++11 8.5/16 specifies that if the initialiser is (), the object is value-initialised.
C++11 8.5/7 defines value initialisation.
Initialisations are covered in [dcl.init] (aka 8.5)
Point 10 says:
An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized.
Value-initialisation is, put simply, default construction for classes and zero-initialisation for non-class types.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What do the following phrases mean in C++: zero-, default- and value-initialization?
If I have a class for example:
class Info
{
int x;
int y;
};
which I used to created an object,
Info *p = new Info();
Does the brackets beside Info mean i'm value initializing it? How does it different from this, Info *p = new Info; ?
I know there is a question which differentiate between different meanings in new and old C++ language but I want to know the semantic difference between default and value initialization e.g. Does value initialization means initializing something to zero?
A declared variable can be Zero Initialized, Value Initialized or Default Initialized.
In your example:
Info *p = new Info(); <------- Value Initialization
Info *p = new Info; <------- Default Initialization
The C++03 Standard 8.5/5 aptly defines each:
To zero-initialize an object of type T means:
— if T is a scalar type (3.9), the object is set to the value of 0 (zero) converted to T;
— if T is a non-union class type, each nonstatic data member and each base-class subobject
is zero-initialized;
— if T is a union type, the object’s first named data member is zero-initialized;
— if T is an array type, each element is zero-initialized;
— if T is a reference type, no initialization is performed.
To default-initialize an object of type T means:
— if T is a non-POD class type (clause 9), the default constructor for T is called (and the
initialization is ill-formed if T has no accessible default constructor);
— if T is an array type, each element is default-initialized;
— otherwise, the object is zero-initialized.
To value-initialize an object of type T means:
— if T is a class type (clause 9) with a user-declared constructor (12.1), then the default
constructor for T is called (and the initialization is ill-formed if T has no accessible
default constructor);
— if T is a non-union class type without a user-declared constructor, then every non-static
data member and base-class component of T is value-initialized;
— if T is an array type, then each element is value-initialized;
— otherwise, the object is zero-initialized
WCHAR wszFoo[CONSTANT_BAR] = {0};
I've never seen something like {0} used in C++ as part of the language. And I have no idea how to search for a question like this online. What is it?
See array initialization.
Missing initialization values use zero
If an explicit array size is
specified, but an shorter
initiliazation list is specified, the
unspecified elements are set to zero.
float pressure[10] = {2.101, 2.32,
1.44};
This not only initializes the first
three values, but all remaining
elements are set to 0.0. To initialize
an array to all zeros, initialize only
the first value.
$8.5.1/7 -
"If there are fewer initializers in
the list than there are members in the
aggregate, then each member not
explicitly initialized shall be
value-initialized (8.5)."
All this means, is that there is an explict request to initialize first element to 0. Since initializers are not specified for the remaining elements, they are value-initialized. This in case of WCHARs means are initialized to 0.
What does value initialized means? Here is what the Standard says in $8.5 (italics are mine)
To value-initialize an object of type
T means:
— if T is a class type
(clause 9) with a user-declared
constructor (12.1), then the default
constructor for T is called (and the
initialization is ill-formed if T has
no accessible default constructor);
—
if T is a non-union class type without
a user-declared constructor, then
every non-static data member and
base-class component of T is
value-initialized;
— if T is an array
type, then each element is
value-initialized;
— otherwise, the
object is zero-initialized <------
WCHAR will fit here
To zero-initialize an object of type T
means:
— if T is a scalar type (3.9),
the object is set to the value of 0
(zero) converted to T; <------ WCHAR
will fit here
— if T is a non-union
class type, each nonstatic data member
and each base-class subobject is
zeroinitialized;
— if T is a union
type, the object’s first named data
member89) is zero-initialized;
— if T
is an array type, each element is
zero-initialized;
— if T is a
reference type, no initialization is
performed.
It's initializing an array.
float p1[1000]; // No intitialization.
float p2[1000] = {0.0}; // All 1000 values initialized to zero.
More here: C++ Notes: Array Initialization
It means initialize all elements of wszFoo to zero.