Default Initialization Vs. Value Initialization

J

JKop

What's the difference between them?

Take the following:

#include <iostream>


struct Blah
{
int k;
const char* p_b;
std::string c;
};


I used to think that when you did:


Blah poo = Blah();


that all its members got "default initialized", which resulted in:

poo.k == 0
poo.p_b == 0 (null pointer value)
poo.c (Gets the default std::string constructor called with no arguments)


I'm correct in the above, yes? But now I hear that things have changed and
that

Blah poo = Blah();

results in "value intialization"...

So what's "value intialization" and how is it different from "default
initialization"?


-JKop
 
R

Ron Natalie

JKop said:
So what's "value intialization" and how is it different from "default
initialization"?

To understand value initialization, you have to understand that while POD types have
default initialization (zero initialization), some times the default initialization is just omitted.
[This I see as a major defect in the language, but it makes it performance compatible
with C so it's hard to convince people of the stupidity.]

The problem is that types such as:
struct S {
int i;
T t;
};

Get different behavior in the old standard based on the type of T (if T is POD then S is
POD and you get zero initialization and i is hence zero initialized, if T is not POD, then i doesn't
get initialized because S's default constructor doesn't touch it).

To fix this, most places where default initialization occured are replaced with value initialization.
And value initialization rather than using "PODness" of a determining factor looks for the presence
of a user defined constructor to determine whether to recursively value-initialize or to just run the
consturctor...
 
J

JKop

Ron Natalie posted:
JKop said:
So what's "value intialization" and how is it different from "default
initialization"?

To understand value initialization, you have to understand that while
POD types have default initialization (zero initialization), some times
the default initialization is just omitted. [This I see as a major
defect in the language, but it makes it performance compatible with C
so it's hard to convince people of the stupidity.]

The problem is that types such as:
struct S {
int i;
T t;
};

Get different behavior in the old standard based on the type of T (if T
is POD then S is POD and you get zero initialization and i is hence
zero initialized, if T is not POD, then i doesn't get initialized
because S's default constructor doesn't touch it).

To fix this, most places where default initialization occured are
replaced with value initialization. And value initialization rather
than using "PODness" of a determining factor looks for the presence of
a user defined constructor to determine whether to recursively
value-initialize or to just run the consturctor...


Okay... I think I understand. Given:

struct Blah
{
int i;
std::string k;
};


With regard to the *old* standard, when you did:

Blah poo = Blah();

Then "poo.i" didn't get... let's just call it
"initialized".


But... with the new standard, when you do:

Blah poo = Blah();

then "poo.i" *does* get initialized.


BTW, Blah is a POD, right? I'd classify it as so in
anyway...


Would I be right in thinking that the following are the
factors which render a structure *no longer* a POD:

A) a constructor (including a copy constructor)
B) private or protected members

Well... if you look at Blah, it has neither, hence you can
define one as so:

std::string a("MONKEY!");

Blah poo = { 5, a };

And as such it's a POD... right?


-JKop
 
H

Howard

Would I be right in thinking that the following are the
factors which render a structure *no longer* a POD:

A) a constructor (including a copy constructor)

Not relevant. Even if you don't supply a constructor, the compiler will
supply one.
B) private or protected members

Also not relevant.

A POD type is either a built-in type, or contains only built-in types, or
contains only POD members (not pointer to such) or arrays of such. (I think
I've covered it, but maybe not. It's been described many times..try
searching on groups.google.com.)

-Howard
 
R

Ron Natalie

JKop said:
With regard to the *old* standard, when you did:

Blah poo = Blah();

Then "poo.i" didn't get... let's just call it
"initialized".
But... with the new standard, when you do:
then "poo.i" *does* get initialized.
Correct.


BTW, Blah is a POD, right? I'd classify it as so in
anyway...

No, Blah is NOT POD, which is the problem. It it had been POD,
then the default initialization behavior would have been zero initialization.
Lets say you had
struct PODBlah {
int i;
char* c;
};
PODBlah poo = PODBlah();

Both PODBlah.i and PODBlah.c get default initalized because PODBlah is POD.

Would I be right in thinking that the following are the
factors which render a structure *no longer* a POD:

A) a constructor (including a copy constructor)
B) private or protected members

You missed one important one. It can't have any non-static
data members of non-POD type. Since std::string is not POD,
then any class that contains it is also NOT POD (although it may
be an aggregate).

A POD-class is an aggregate that has no non-static data members that
aren't POD.

Aggregate classes have no user declared constructors, no private or protected
non-static data members, no base classes, and no virtual functions.
std::string a("MONKEY!");

Blah poo = { 5, a };

And as such it's a POD... right?

Nope, it's an aggregate (and hence you can use the { } aggregate initializer syntax).
But it's not POD.
 
R

Ron Natalie

Howard said:
contains only POD members (not pointer to such) or arrays of such. (I think
I've covered it, but maybe not. It's been described many times..try
searching on groups.google.com.)

Not.
 
J

JKop

A POD type is either a built-in type, or contains only built-in types,
or contains only POD members (not pointer to such) or arrays of such.
(I think I've covered it, but maybe not. It's been described many
times..try searching on groups.google.com.)


That's a paradox if I've ever seen one.

A house is made of bricks, but bricks are still made of molecules!

Similarly, a structure may be made up of other structures, but these other
structures are still made up of intrinsic types.


-JKop
 
H

Howard

Ron Natalie said:
"Howard" <[email protected]> wrote in message
A POD type is either a built-in
type, or
contains only built-in types, or

Not.

:)

Not the best explanation there, Ron. But I've read your other post, and
that explains it better. I wasn't aware of the user-created constructor
being relevant to the issues though. Any idea why that's relevant? Because
it interferes with the default initialization scheme?

-Howard
 
R

Ron Natalie

Howard said:
:)

Not the best explanation there, Ron. But I've read your other post, and
that explains it better. I wasn't aware of the user-created constructor
being relevant to the issues though. Any idea why that's relevant? Because
it interferes with the default initialization scheme?

You have to realize that that is a requirement inheritted from aggregates. You can't
have a user declared construtor as how would that boogie with the aggregate initialization
sequence (you can't both have a constructor and a member-wise constructor).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,734
Messages
2,569,441
Members
44,832
Latest member
GlennSmall

Latest Threads

Top