Value intitialization, default initialization

Jan 24, 2011 at 8:57pm
This default initialization and value initialization business is killing me. It is rephrased in every next version of the standard. I can understand the basic idea, but I can not identify the exact rules that govern the behavior that I observe with mingw/gnu gcc v3.4.5.

Here is an example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>

using namespace std;

struct NonPod {
    int value;
    NonPod() : value() { }
};

struct Pod {
    int value;
};

int main()
{
    // value and copy initialization
    NonPod a = NonPod();
    // default initialization
    NonPod b;
    // value and copy initialization
    Pod c = Pod();
    // default initialization
    Pod d;

    cout << a.value << endl; // output: 0
    cout << b.value << endl; // output: 0
    cout << c.value << endl; // output: 0
    cout << d.value << endl; // output: ..some garbage
}


Now, here is excerpt from the `03 standard (according to some source that I can not confirm presently).
8.5/5:
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 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.

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.

Can you please point me (very briefly) to the lines relevant for the above example.

Also, I am wondering, how can I request value initialization without using the copy initialization syntax. I mean, the line T x; requests default initialization, which is a volatile. The line T x = T(); requests value initialization, but MAY invoke the copy constructor (although it didn't in gnu gcc). The line T x(); declares a function with no parameters and return type T. So, how can I value-initialize without fear that the copy constructor may be invoked. Of course, if the type has copy constructor, then I probably don't need to value-initialize in the first place, but suppose I don't know that. I mean, suppose I am using somebody else's code in some company and the code may change over time and I don't want to rely on anything.

Regards
Jan 24, 2011 at 9:00pm
closed account (zb0S216C)
Replace your code with this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>

using namespace std;

struct NonPod {
    int value;
    NonPod() : value( 0 ) { }
};

struct Pod {
    Pod( void ) : value( 0 ) { }
    int value;
};

int main()
{
    // value and copy initialization
    NonPod a;
    // default initialization
    NonPod b;
    // value and copy initialization
    Pod c;
    // default initialization
    Pod d;

    cout << a.value << endl; // output: 0
    cout << b.value << endl; // output: 0
    cout << c.value << endl; // output: 0
    cout << d.value << endl; // output: ..some garbage
}
Jan 24, 2011 at 9:02pm
closed account (zb0S216C)
Note: If you do this:
NodPod a = NonPod( )
Your're trying to call the class/struct's default constructor manually which is disallowed. Also, if you don't initialize a class/struct member, then it holds "garbage" such as this: 21982368.
Last edited on Jan 24, 2011 at 9:06pm
Jan 24, 2011 at 9:14pm
Framework wrote:
Replace your code with this:
Do you mean that it would be more proper to always use default initialization?
Your're trying to call the class/struct's default constructor manually which is disallowed.
May be. But it does compile with gcc. Is this gcc specific? After all, I can use int i = int().
Also, if you don't initialize a class/struct member, then it holds "garbage" such as this: 21982368.
Actually, if I don't initialize anything with explicit call to its default constructor, if it doesn't even have default constructor, then it will hold garbage. This is what default initialization means in my opinion.
Jan 24, 2011 at 9:19pm
closed account (zb0S216C)
Actually, if I don't initialize anything with explicit call to its default constructor, if it doesn't even have default constructor, then it will hold garbage. This is what default initialization means in my opinion.

I've tried printing the value of an uninitialized class/struct member and it gave me "garbage" until I initialized it with a value. Try it yourself.

May be. But it does compile with gcc. Is this gcc specific? After all, I can use int i = int().

Yes it does, I'm sorry, my mistake.

Do you mean that it would be more proper to always use default initialization?

In my opinion, class/struct members should always be initialized in the constructor. Default constructors don't initialize the members, they only set-up the class/struct I think.
Last edited on Jan 24, 2011 at 9:21pm
Jan 24, 2011 at 9:28pm
You also need to be aware of what an aggregate is. simeonz's Pod is an aggregate, Framework's is not (because of the constructor).
Last edited on Jan 24, 2011 at 9:29pm
Jan 24, 2011 at 9:29pm
Framework wrote:
I've tried printing the value of an uninitialized class/struct member and it gave me "garbage" until I initialized it with a value. Try it yourself.

Exactly the reason why I want to initialize it with the explicit call to its default constructor. I mean, if S is some simple structure with no constructor, then S x; leaves the members uninitialized, and S x = S(); initializes them. On the other hand if S is not a simple structure and has a copy and default constructor, then S x = S(); may (or may not) invoke the copy constructor. But I can not use S x(); to avoid the copy constructor for certain, because this is a function declaration.

And I still can not interpret the standard on when a value is initialized and when it will be garbage. I mean, isn't it a fuzz.
Jan 24, 2011 at 9:32pm
PanGalactic wrote:
You also need to be aware of what an aggregate is.
What is the difference between aggregate and POD type? (Not that I am certain of what a POD type is, except that I understand that structures that worked in C are now POD types.)
Jan 24, 2011 at 9:41pm
closed account (zb0S216C)
if S is some simple structure with no constructor, then S x; leaves the members uninitialized, and S x = S(); initializes them. On the other hand if S is not a simple structure and has a copy and default constructor, then S x = S(); may (or may not) invoke the copy constructor.


I was a bit unsure about this, so, after experimenting with your code, it turns out that you're correct. I'll remember this for next time.
Jan 24, 2011 at 9:42pm
This should help. It has one of the most concise explanations I have read.

http://en.wikipedia.org/wiki/C%2B%2B_classes#Differences_between_struct_and_classes_in_C.2B.2B

The key take-away is that an aggregate can be initialized with an initializer list.

 
Pod d = {1}; // Works for simeonz's Pod, does not work for Framework's Pod. 
Jan 24, 2011 at 9:55pm
PanGalactic wrote:
This should help. It has one of the most concise explanations I have read.

http://en.wikipedia.org/wiki/C%2B%2B_classes#Differences_between_struct_and_classes_in_C.2B.2B

Thanks. What other programming languages do you recommend if I decide to switch from C++?

Seriously though, the explanations for POD types seem close to those in the current draft of the standard - in other words, impossible to memorize. According to the definition in wiki, aggregates are a limited version of POD. EDIT: hmm, not exactly, aggregates allow user-defined destructors.

I still hope that someone clarifies a bit the application of the rules for value and default initialization in my example. Which of them get activated to produce the observed result. And how to use value initialization without copy initialization.
Last edited on Jan 24, 2011 at 9:57pm
Jan 24, 2011 at 10:04pm
In your original example, NonPod's value member will be initialized to zero no matter what syntax you use to default
construct it. Pod's value member will be uninitialized (read: could be anything) no matter what syntax you use to
default construct it.
Jan 24, 2011 at 10:10pm
simeonz wrote:
What other programming languages do you recommend if I decide to switch from C++?

Well, no one should know just one language. I like Python as a good compliment to C++.
Jan 24, 2011 at 10:11pm
jsmith wrote:
In your original example, NonPod's value member will be initialized to zero no matter what syntax you use to default construct it.

I agree. (To the extent of my understanding.)

Pod's value member will be uninitialized (read: could be anything) no matter what syntax you use to default construct it.

But if you read the comments in the example, you will see that it depends on the use default vs value initialization. Really, its in the comments that show the output. It also matches my very vague interpretation of the quoted excerpt from the standard.
Jan 24, 2011 at 10:14pm
PanGalactic wrote:
Well, no one should know just one language. I like Python as a good compliment to C++.
So, what language will be my other language if I learn Python? :)

EDIT: True. I wanted to learn Python for some time now, since it is frequently used by C++ frameworks and toolchains as the scripting language.
Last edited on Jan 24, 2011 at 10:17pm
Jan 24, 2011 at 10:29pm
I myself have made a little list of things to learn (higher = higher priority):
C++
Python
ASM
Lisp
Java

That's because I want to have a rich set of tools at my disposal to apply commonly used languages (C++ / Java) which can be extended (Python) and accelerated or analyzed (ASM). Lisp is in the list because it seems a nice addition, since functional languages seem to be neat. Then again, that's just my little list that should keep me busy (I'm good on STL C++ and learning Qt while I'm starting up on Python with little programs), it's completely subjective and anyone is free to disagree. . .. In fact, I'd love to have people that disagree, to shake this up a bit and get more potential out of my learning time.
Jan 24, 2011 at 10:49pm
closed account (zb0S216C)
What about Lua?
Jan 24, 2011 at 10:59pm
I don't see in your quote any form that a variable could have garbage.
About the c.value, don't forget that garbage could be 0, and your compiler likes to optimize things.

Is there a 03 standard? I thought that the 98 was the last one.
Jan 24, 2011 at 11:15pm
ne555 wrote:
I don't see in your quote any form that a variable could have garbage.
About the c.value, don't forget that garbage could be 0, and your compiler likes to optimize things.

Yes, but it is 0 repeatedly. Of course, that could be coincidence too, but how would I argue then?

Is there a 03 standard? I thought that the 98 was the last one.

I thought so too. It turns out there was a "technical corrigendum" at 03 like what it says here http://www.open-std.org/jtc1/sc22/wg21/docs/standards. The text regarding default and value initialization changed significantly then.
Topic archived. No new replies allowed.