Struct Value Initialization in C++, VS2013 [duplicate] - c++

Does the default constructor (created by the compiler) initialize built-in-types?

Implicitly defined (by the compiler) default constructor of a class does not initialize members of built-in types.
However, you have to keep in mind that in some cases the initialization of a instance of the class can be performed by other means. Not by default constructor, nor by constructor at all.
For example, there's a widespread incorrect belief that for class C the syntax C() always invokes default constructor. In reality though, the syntax C() performs so called value-initialization of the class instance. It will only invoke the default constructor if it is user-declared. (That's in C++03. In C++98 - only if the class is non-POD). If the class has no user-declared constructor, then the C() will not call the compiler-provided default constructor, but rather will perform a special kind of initialization that does not involve the constructor of C at all. Instead, it will directly value-initialize every member of the class. For built-in types it results in zero-initialization.
For example, if your class has no user-declared constructor
class C {
public:
int x;
};
then the compiler will implicitly provide one. The compiler-provided constructor will do nothing, meaning that it will not initialize C::x
C c; // Compiler-provided default constructor is used
// Here `c.x` contains garbage
Nevertheless, the following initializations will zero-initialize x because they use the explicit () initializer
C c = C(); // Does not use default constructor for `C()` part
// Uses value-initialization feature instead
assert(c.x == 0);
C *pc = new C(); // Does not use default constructor for `C()` part
// Uses value-initialization feature instead
assert(pc->x == 0);
The behavior of () initializer is different in some respects between C++98 and C++03, but not in this case. For the above class C it will be the same: () initializer performs zero initialization of C::x.
Another example of initialization that is performed without involving constructor is, of course, aggregate initialization
C c = {}; // Does not use any `C` constructors at all. Same as C c{}; in C++11.
assert(c.x == 0);
C d{}; // C++11 style aggregate initialization.
assert(d.x == 0);

I'm not quite certain what you mean, but:
struct A { int x; };
int a; // a is initialized to 0
A b; // b.x is initialized to 0
int main() {
int c; // c is not initialized
int d = int(); // d is initialized to 0
A e; // e.x is not initialized
A f = A(); // f.x is initialized to 0
}
In each case where I say "not initialized" - you might find that your compiler gives it a consistent value, but the standard doesn't require it.
A lot of hand-waving gets thrown around, including by me, about how built-in types "in effect" have a default constructor. Actually default initialization and value initialization are defined terms in the standard, which personally I have to look up every time. Only classes are defined in the standard to have an implicit default constructor.

For all practical purposes - no.
However for implementations that are technically compliant with the C++ standard, the answer is that it depends whether the object is POD or not and on how you initialize it.
According to the C++ standard:
MyNonPodClass instance1;//built in members will not be initialized
MyPodClass instance2;//built in members will be not be initialized
MyPodClass* instance3 = new MyPodClass;//built in members will not be initialized
MyPodClass* instance3 = new MyPodClass() ;//built in members will be zero initialized
However, in the real world, this isn't well supported so don't use it.
The relevant parts of the standard are section 8.5.5 and 8.5.7

As per the standard, it doesn't unless you explicitly initialize in initializer list

As previous speakers have stated - no, they are not initialized.
This is actually a source for really strange errors as modern OSs tend to fill newly allocated memory regions with zeroes. If you expect that, it might work the first time. However, as your application keeps running, delete-ing and new-ing objects, you will sooner or later end up in a situation where you expect zeroes but a non-zero leftover from an earlier object sits.
So, why is this then, isn't all new-ed data newly allocated? Yes, but not always from the OS. The OS tends to work with larger chunks of memory (e.g. 4MB at a time) so all the tiny one-word-here-three-bytes-there-allocations and deallocations are handled in uyserspace, and thus not zeroed out.
PS. I wrote "tend to", i.e. you can't even rely on success the first time...

Technically it does initialize them -- by using their default constructor, which incidentally does nothing but allocate the memory for them.
If what you wanted to know is whether or not they are set to something sane like 0 for ints, then the answer is "no".

No. The default constructor allocates memory and calls the no-argument constructor of any parents.

Related

Why calling class members with primitive datatypes works without being initialized? [duplicate]

Does the default constructor (created by the compiler) initialize built-in-types?
Implicitly defined (by the compiler) default constructor of a class does not initialize members of built-in types.
However, you have to keep in mind that in some cases the initialization of a instance of the class can be performed by other means. Not by default constructor, nor by constructor at all.
For example, there's a widespread incorrect belief that for class C the syntax C() always invokes default constructor. In reality though, the syntax C() performs so called value-initialization of the class instance. It will only invoke the default constructor if it is user-declared. (That's in C++03. In C++98 - only if the class is non-POD). If the class has no user-declared constructor, then the C() will not call the compiler-provided default constructor, but rather will perform a special kind of initialization that does not involve the constructor of C at all. Instead, it will directly value-initialize every member of the class. For built-in types it results in zero-initialization.
For example, if your class has no user-declared constructor
class C {
public:
int x;
};
then the compiler will implicitly provide one. The compiler-provided constructor will do nothing, meaning that it will not initialize C::x
C c; // Compiler-provided default constructor is used
// Here `c.x` contains garbage
Nevertheless, the following initializations will zero-initialize x because they use the explicit () initializer
C c = C(); // Does not use default constructor for `C()` part
// Uses value-initialization feature instead
assert(c.x == 0);
C *pc = new C(); // Does not use default constructor for `C()` part
// Uses value-initialization feature instead
assert(pc->x == 0);
The behavior of () initializer is different in some respects between C++98 and C++03, but not in this case. For the above class C it will be the same: () initializer performs zero initialization of C::x.
Another example of initialization that is performed without involving constructor is, of course, aggregate initialization
C c = {}; // Does not use any `C` constructors at all. Same as C c{}; in C++11.
assert(c.x == 0);
C d{}; // C++11 style aggregate initialization.
assert(d.x == 0);
I'm not quite certain what you mean, but:
struct A { int x; };
int a; // a is initialized to 0
A b; // b.x is initialized to 0
int main() {
int c; // c is not initialized
int d = int(); // d is initialized to 0
A e; // e.x is not initialized
A f = A(); // f.x is initialized to 0
}
In each case where I say "not initialized" - you might find that your compiler gives it a consistent value, but the standard doesn't require it.
A lot of hand-waving gets thrown around, including by me, about how built-in types "in effect" have a default constructor. Actually default initialization and value initialization are defined terms in the standard, which personally I have to look up every time. Only classes are defined in the standard to have an implicit default constructor.
For all practical purposes - no.
However for implementations that are technically compliant with the C++ standard, the answer is that it depends whether the object is POD or not and on how you initialize it.
According to the C++ standard:
MyNonPodClass instance1;//built in members will not be initialized
MyPodClass instance2;//built in members will be not be initialized
MyPodClass* instance3 = new MyPodClass;//built in members will not be initialized
MyPodClass* instance3 = new MyPodClass() ;//built in members will be zero initialized
However, in the real world, this isn't well supported so don't use it.
The relevant parts of the standard are section 8.5.5 and 8.5.7
As per the standard, it doesn't unless you explicitly initialize in initializer list
As previous speakers have stated - no, they are not initialized.
This is actually a source for really strange errors as modern OSs tend to fill newly allocated memory regions with zeroes. If you expect that, it might work the first time. However, as your application keeps running, delete-ing and new-ing objects, you will sooner or later end up in a situation where you expect zeroes but a non-zero leftover from an earlier object sits.
So, why is this then, isn't all new-ed data newly allocated? Yes, but not always from the OS. The OS tends to work with larger chunks of memory (e.g. 4MB at a time) so all the tiny one-word-here-three-bytes-there-allocations and deallocations are handled in uyserspace, and thus not zeroed out.
PS. I wrote "tend to", i.e. you can't even rely on success the first time...
Technically it does initialize them -- by using their default constructor, which incidentally does nothing but allocate the memory for them.
If what you wanted to know is whether or not they are set to something sane like 0 for ints, then the answer is "no".
No. The default constructor allocates memory and calls the no-argument constructor of any parents.

Are members of a class with defaulted constructors zero-initialized? [duplicate]

Does the default constructor (created by the compiler) initialize built-in-types?
Implicitly defined (by the compiler) default constructor of a class does not initialize members of built-in types.
However, you have to keep in mind that in some cases the initialization of a instance of the class can be performed by other means. Not by default constructor, nor by constructor at all.
For example, there's a widespread incorrect belief that for class C the syntax C() always invokes default constructor. In reality though, the syntax C() performs so called value-initialization of the class instance. It will only invoke the default constructor if it is user-declared. (That's in C++03. In C++98 - only if the class is non-POD). If the class has no user-declared constructor, then the C() will not call the compiler-provided default constructor, but rather will perform a special kind of initialization that does not involve the constructor of C at all. Instead, it will directly value-initialize every member of the class. For built-in types it results in zero-initialization.
For example, if your class has no user-declared constructor
class C {
public:
int x;
};
then the compiler will implicitly provide one. The compiler-provided constructor will do nothing, meaning that it will not initialize C::x
C c; // Compiler-provided default constructor is used
// Here `c.x` contains garbage
Nevertheless, the following initializations will zero-initialize x because they use the explicit () initializer
C c = C(); // Does not use default constructor for `C()` part
// Uses value-initialization feature instead
assert(c.x == 0);
C *pc = new C(); // Does not use default constructor for `C()` part
// Uses value-initialization feature instead
assert(pc->x == 0);
The behavior of () initializer is different in some respects between C++98 and C++03, but not in this case. For the above class C it will be the same: () initializer performs zero initialization of C::x.
Another example of initialization that is performed without involving constructor is, of course, aggregate initialization
C c = {}; // Does not use any `C` constructors at all. Same as C c{}; in C++11.
assert(c.x == 0);
C d{}; // C++11 style aggregate initialization.
assert(d.x == 0);
I'm not quite certain what you mean, but:
struct A { int x; };
int a; // a is initialized to 0
A b; // b.x is initialized to 0
int main() {
int c; // c is not initialized
int d = int(); // d is initialized to 0
A e; // e.x is not initialized
A f = A(); // f.x is initialized to 0
}
In each case where I say "not initialized" - you might find that your compiler gives it a consistent value, but the standard doesn't require it.
A lot of hand-waving gets thrown around, including by me, about how built-in types "in effect" have a default constructor. Actually default initialization and value initialization are defined terms in the standard, which personally I have to look up every time. Only classes are defined in the standard to have an implicit default constructor.
For all practical purposes - no.
However for implementations that are technically compliant with the C++ standard, the answer is that it depends whether the object is POD or not and on how you initialize it.
According to the C++ standard:
MyNonPodClass instance1;//built in members will not be initialized
MyPodClass instance2;//built in members will be not be initialized
MyPodClass* instance3 = new MyPodClass;//built in members will not be initialized
MyPodClass* instance3 = new MyPodClass() ;//built in members will be zero initialized
However, in the real world, this isn't well supported so don't use it.
The relevant parts of the standard are section 8.5.5 and 8.5.7
As per the standard, it doesn't unless you explicitly initialize in initializer list
As previous speakers have stated - no, they are not initialized.
This is actually a source for really strange errors as modern OSs tend to fill newly allocated memory regions with zeroes. If you expect that, it might work the first time. However, as your application keeps running, delete-ing and new-ing objects, you will sooner or later end up in a situation where you expect zeroes but a non-zero leftover from an earlier object sits.
So, why is this then, isn't all new-ed data newly allocated? Yes, but not always from the OS. The OS tends to work with larger chunks of memory (e.g. 4MB at a time) so all the tiny one-word-here-three-bytes-there-allocations and deallocations are handled in uyserspace, and thus not zeroed out.
PS. I wrote "tend to", i.e. you can't even rely on success the first time...
Technically it does initialize them -- by using their default constructor, which incidentally does nothing but allocate the memory for them.
If what you wanted to know is whether or not they are set to something sane like 0 for ints, then the answer is "no".
No. The default constructor allocates memory and calls the no-argument constructor of any parents.

why do I need a constructor function?

#include<iostream>
using namespace std;
class A {
public:
int i;
};
int main() {
const A aa; //This is wrong, I can't compile it! The implicitly-defined constructor does not initialize ‘int A::i’
}
when I use
class A {
public:
A() {}
int i;
};
this is ok! I can compile it! why I can't compile it when I use the implicitly-defined constructor?
why the implicit-defined constructor does not work?
It does work, but one of the language rules is that it can't be used to initialise a const object unless it initialises all the members; and it doesn't initialise members with trivial types like int. That usually makes sense, since being const there's no way to give them a value later.
(That's a slight simplification; see the comments for chapter and verse from the language standard.)
If you define your own constructor, then you're saying that you know what you're doing and don't want that member initialised. The compiler will let you use that even for a const object.
If you want to set it to zero, then you could value-initialise the object:
const A aa {}; // C++11 or later
const A aa = A(); // historic C++
If you want to set it to another value, or set it to zero without the user having to specify value-initialisation, then you'll need a constructor that initialises the member:
A() : i(whatever) {}
why the implicit-defined constructor does not work?
Because the C++ standard says so:
[dcl.init] paragraph 7:
If a program calls for the default initialization of an object of a const-qualified type T, T shall be a class type with a user-provided default constructor.
This ensures that you don't create a const object containing uninitialized data that cannot be initialized later.
To initialize a const-qualified object you need to have a user-provided default constructor or use an initialiser:
const A aa = A();
Here the object aa is initialized with the expression A() which is a value-initialized object. You can value-initialize a class type without a default constructor, because value-initialization will set values to zero if there is no default constructor for the type.
However, the rule in the standard is too strict, as it forbids using implicitly-defined constructors even when there are no data members or all data members have sensible default constructors, so there is a defect report against the standard proposing to change it, see issue 253.
You don't state what compiler you're using. I've tried this with VS2012 and get a warning C4269.
The reason this is a problem is because aa is const. Because you haven't defined a constructor a default one is used and so i can be anything. It also cannot be changed (because aa is const).
If you define a constructor, it is assumed that you are happy with the initialization of i. Although, in this case you haven't actually changed the behaviour.
From this MSDN page
Since this instance of the class is generated on the stack, the initial value of m_data can be anything. Also, since it is a const instance, the value of m_data can never be changed.
Because i is not initialized.
class A
{
public:
A()
{
i =0;
}
int i;
};
"Implicit constructor" means a constructor generated for you automatically and generates an error because it realizes it is not able to initialize the value of i. This can be a no-args constructor, a copy constructor or (as of C++11) a move constructor.
why the implicit-defined constructor does not work?
It works just fine, but it does not decide what your default values are implicitly (and as such, it only calls default constructors for it's members, but not for POD types).
If you want the constructor to initialize your members with certain values you have to explicitly write that (i.e. add a default constructor explicitly).
Making a default (implicit) constructor initialize POD members with a chosen value (like zero for example) would add extra computing cycles (and slow your program down) when you don't need that. C++ is designed to behave as if you (the programmer) know what you are doing (i.e. if you do not initialize your members explicitly, the compiler assumes you don't care what default value you get).

Does the default constructor initialize built-in types?

Does the default constructor (created by the compiler) initialize built-in-types?
Implicitly defined (by the compiler) default constructor of a class does not initialize members of built-in types.
However, you have to keep in mind that in some cases the initialization of a instance of the class can be performed by other means. Not by default constructor, nor by constructor at all.
For example, there's a widespread incorrect belief that for class C the syntax C() always invokes default constructor. In reality though, the syntax C() performs so called value-initialization of the class instance. It will only invoke the default constructor if it is user-declared. (That's in C++03. In C++98 - only if the class is non-POD). If the class has no user-declared constructor, then the C() will not call the compiler-provided default constructor, but rather will perform a special kind of initialization that does not involve the constructor of C at all. Instead, it will directly value-initialize every member of the class. For built-in types it results in zero-initialization.
For example, if your class has no user-declared constructor
class C {
public:
int x;
};
then the compiler will implicitly provide one. The compiler-provided constructor will do nothing, meaning that it will not initialize C::x
C c; // Compiler-provided default constructor is used
// Here `c.x` contains garbage
Nevertheless, the following initializations will zero-initialize x because they use the explicit () initializer
C c = C(); // Does not use default constructor for `C()` part
// Uses value-initialization feature instead
assert(c.x == 0);
C *pc = new C(); // Does not use default constructor for `C()` part
// Uses value-initialization feature instead
assert(pc->x == 0);
The behavior of () initializer is different in some respects between C++98 and C++03, but not in this case. For the above class C it will be the same: () initializer performs zero initialization of C::x.
Another example of initialization that is performed without involving constructor is, of course, aggregate initialization
C c = {}; // Does not use any `C` constructors at all. Same as C c{}; in C++11.
assert(c.x == 0);
C d{}; // C++11 style aggregate initialization.
assert(d.x == 0);
I'm not quite certain what you mean, but:
struct A { int x; };
int a; // a is initialized to 0
A b; // b.x is initialized to 0
int main() {
int c; // c is not initialized
int d = int(); // d is initialized to 0
A e; // e.x is not initialized
A f = A(); // f.x is initialized to 0
}
In each case where I say "not initialized" - you might find that your compiler gives it a consistent value, but the standard doesn't require it.
A lot of hand-waving gets thrown around, including by me, about how built-in types "in effect" have a default constructor. Actually default initialization and value initialization are defined terms in the standard, which personally I have to look up every time. Only classes are defined in the standard to have an implicit default constructor.
For all practical purposes - no.
However for implementations that are technically compliant with the C++ standard, the answer is that it depends whether the object is POD or not and on how you initialize it.
According to the C++ standard:
MyNonPodClass instance1;//built in members will not be initialized
MyPodClass instance2;//built in members will be not be initialized
MyPodClass* instance3 = new MyPodClass;//built in members will not be initialized
MyPodClass* instance3 = new MyPodClass() ;//built in members will be zero initialized
However, in the real world, this isn't well supported so don't use it.
The relevant parts of the standard are section 8.5.5 and 8.5.7
As per the standard, it doesn't unless you explicitly initialize in initializer list
As previous speakers have stated - no, they are not initialized.
This is actually a source for really strange errors as modern OSs tend to fill newly allocated memory regions with zeroes. If you expect that, it might work the first time. However, as your application keeps running, delete-ing and new-ing objects, you will sooner or later end up in a situation where you expect zeroes but a non-zero leftover from an earlier object sits.
So, why is this then, isn't all new-ed data newly allocated? Yes, but not always from the OS. The OS tends to work with larger chunks of memory (e.g. 4MB at a time) so all the tiny one-word-here-three-bytes-there-allocations and deallocations are handled in uyserspace, and thus not zeroed out.
PS. I wrote "tend to", i.e. you can't even rely on success the first time...
Technically it does initialize them -- by using their default constructor, which incidentally does nothing but allocate the memory for them.
If what you wanted to know is whether or not they are set to something sane like 0 for ints, then the answer is "no".
No. The default constructor allocates memory and calls the no-argument constructor of any parents.

Difference between A* pA = new A; and A* pA = new A();

in C++, what is the exact difference between both following dynamic object creations :
A* pA = new A;
A* pA = new A();
I did some tests, but it seems that in both cases, the default constructor is called and only it. I'm looking for any difference about performance...
Thanks
If A is a POD-type, then new A will allocate a new A object but leave it with an indeterminate value, otherwise new A will default initialize the new object.
In all cases new A() will value initialize the new A object.
This is obviously different behaviour for POD types but also affects non-POD, non-union class types without a used-declared constructor.
E.g.
struct A
{
int a;
std::string s;
};
A is a non-POD class type without a user-declared constructor. When an A is default initialized the implicitly defined constructor is called which calls the default constructor for s (a non-POD type), but a is not initialized.
When an A is value initialized, as it has no used-declared constructor, all of its members are value initialized which means that the default constructor for s is called and a is zero initialized.
ISO 14882:2003 references:
5.3.4 [expr.new]/15: How objects allocated by a new expression are initialized depending on whether the initializer is omitted, a pair of parentheses or otherwise.
8.5 [dcl.init]/5: The meaning of zero initialize, default initialize and value initialize.
12.1 [class.ctor]/7,8: The form of a user-written constructor that matches the behaviour of an implicitly defined default constructor.
12.6.2 [class.base.init]/4: How bases and members which are not listed in a member initializer list of a constructor are initialized.
It's exactly the same, also performance wise :)
The lexer will have to scan two characters less in the first version, so the compilation process is a little faster ;)
please see STL implementing code (e.g. allocator) then you'll understand.