By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,397 Members | 2,552 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,397 IT Pros & Developers. It's quick & easy.

The order of member initialization

P: n/a
The oder of member initialization is the order in which the members are
defined.

So the following code is problematic:

class X{
int i;
int j;
public:
X(int val):j(val),i(j){}
};

But, can I use the following code?

class X{
int i;
int j;
public:
X(int val)
{j=val; i=j;}

};

Oct 2 '06 #1
Share this Question
Share on Google+
11 Replies


P: n/a
Tip: Please give yourself a real name or online handle. Our patience to
answer your questions is proportional to our observations of your patiences
asking them! And when asking us to recite C++ tutorials to you, you should
indicate what you are reading, and where it has failed you.

asdf wrote:
The oder of member initialization is the order in which the members are
defined.

So the following code is problematic:

class X{
int i;
int j;
public:
X(int val):j(val),i(j){}
};
It is indeed undefined behavior, from the moment that j's unassigned value
is accessed.
But, can I use the following code?

class X{
int i;
int j;
public:
X(int val)
{j=val; i=j;}

};
Yes. And now it's bad style, because ... constructor notation is better. It
clearly tells both the compiler and your colleagues what you intend. Both of
them can optimize based on this information.

Now read the /Effective C++/ books, for the category of details you
currently ask about.

--
Phlip
http://www.greencheese.us/ZeekLand <-- NOT a blog!!!
Oct 2 '06 #2

P: n/a
Thanks.

So you mean, the following code is correct although it is a bad style,
right?

class X{
int i;
int j;
public:
X(int val)
{j=val; i=j;}
};

Phlip wrote:
Tip: Please give yourself a real name or online handle. Our patience to
answer your questions is proportional to our observations of your patiences
asking them! And when asking us to recite C++ tutorials to you, you should
indicate what you are reading, and where it has failed you.

asdf wrote:
The oder of member initialization is the order in which the members are
defined.

So the following code is problematic:

class X{
int i;
int j;
public:
X(int val):j(val),i(j){}
};

It is indeed undefined behavior, from the moment that j's unassigned value
is accessed.
But, can I use the following code?

class X{
int i;
int j;
public:
X(int val)
{j=val; i=j;}

};

Yes. And now it's bad style, because ... constructor notation is better. It
clearly tells both the compiler and your colleagues what you intend. Both of
them can optimize based on this information.

Now read the /Effective C++/ books, for the category of details you
currently ask about.

--
Phlip
http://www.greencheese.us/ZeekLand <-- NOT a blog!!!
Oct 2 '06 #3

P: n/a
[Also, please do not top-post. Note I take a little time to edit your text,
so that I produce a complete post that stands-alone. (Not everyone uses
Google Groups!)]

asdf wrote:
So you mean, the following code is correct although it is a bad style,
right?

class X{
int i;
int j;
public:
X(int val)
{j=val; i=j;}
};
Yes. And you will never find a reason to do it.

One reason it's bad is because when you refactor this code (look up
"refactor"), its meaning can change unexpectedly. Same as your other
example, which was also illegal.

--
Phlip
http://www.greencheese.us/ZeekLand <-- NOT a blog!!!
Oct 2 '06 #4

P: n/a

"asdf" <li*********@gmail.comwrote in message
news:11**********************@m7g2000cwm.googlegro ups.com...
The oder of member initialization is the order in which the members are
defined.

So the following code is problematic:

class X{
int i;
int j;
public:
X(int val):j(val),i(j){}
};
Undefined behavior. Why would you want to do it
that way anyway?
>
But, can I use the following code?

class X{
int i;
int j;
public:
X(int val)
{j=val; i=j;}

};
You can, but note that that is not initialization,
it's assignment. Initialize like this:

X(int val) : i(val), j(val) {}

or
X(int val) : j(val), i(val) {}

-Mike
Oct 2 '06 #5

P: n/a
Please don't top post, its for your benefit.
>
Phlip wrote:
Tip: Please give yourself a real name or online handle. Our patience to
answer your questions is proportional to our observations of your patiences
asking them! And when asking us to recite C++ tutorials to you, you should
indicate what you are reading, and where it has failed you.

asdf wrote:
The oder of member initialization is the order in which the members are
defined.
>
So the following code is problematic:
>
class X{
int i;
int j;
public:
X(int val):j(val),i(j){}
};
It is indeed undefined behavior, from the moment that j's unassigned value
is accessed.
But, can I use the following code?
>
class X{
int i;
int j;
public:
X(int val)
{j=val; i=j;}
>
};
Yes. And now it's bad style, because ... constructor notation is better. It
clearly tells both the compiler and your colleagues what you intend. Both of
them can optimize based on this information.

Now read the /Effective C++/ books, for the category of details you
currently ask about.

--
Phlip
http://www.greencheese.us/ZeekLand <-- NOT a blog!!!
asdf wrote:
Thanks.

So you mean, the following code is correct although it is a bad style,
right?

class X{
int i;
int j;
public:
X(int val)
{j=val; i=j;}
};
Its bad style since X::X(int val) : i(val), j(val) { } doesn't involve
assignments nor additional, waisted default construction.

If you program needs to allocate an instance of X, don't you think it
would be more efficient it it initializes the first component and then
the second without having to jump around back and forth in the memory
space? What if you had 10000 of these to instantiate in a sequenced
container? Your platform would be able to initialize all 20000 integers
in one continuous simplified flow.

Lets take the case where i and j are *not* to be assigned the same
values. Its obvious that if i is dependant on j then...
class X
{
int j;
int i; // dependant
public:
X( int n ) : j( n * 10 ), i( j ) { }
};

Oct 2 '06 #6

P: n/a
asdf wrote:
Thanks.

So you mean, the following code is correct although it is a bad
style,
right?

class X{
int i;
int j;
public:
X(int val)
{j=val; i=j;}
};
In this case it is correct, but a bit confusing.

In other cases, where the members are not ints, but const or reference
types, it will not work.
Bo Persson
Oct 2 '06 #7

P: n/a
asdf posted:
The oder of member initialization is the order in which the members are
defined.

So the following code is problematic:

class X{
int i;
int j;
public:
X(int val):j(val),i(j){}
};

g++ issues a warning for this.

But, can I use the following code?

class X{
int i;
int j;
public:
X(int val)
{j=val; i=j;}

};

Why do think you wouldn't be able to?

(1) Control enters the body of the constructor of X.
(2) (At this point, the values of i and j are indeterminant).
(3) The value of "val" is assigned to j.
(4) The value of "j" is assigned to "i".

--

Frederick Gotham
Oct 2 '06 #8

P: n/a
S S

Frederick Gotham wrote:
asdf posted:
The oder of member initialization is the order in which the members are
defined.

So the following code is problematic:

class X{
int i;
int j;
public:
X(int val):j(val),i(j){}
};


g++ issues a warning for this.

But, can I use the following code?

class X{
int i;
int j;
public:
X(int val)
{j=val; i=j;}

};


Why do think you wouldn't be able to?

(1) Control enters the body of the constructor of X.
(2) (At this point, the values of i and j are indeterminant).
(3) The value of "val" is assigned to j.
(4) The value of "j" is assigned to "i".

--

Frederick Gotham
In case of member initialization via initialization list, you
initialize them in order which they are declared. Even if you do not
give any initialization list (but you preferred assignment), in this
case also all members will be initialized default in order which they
are declared but after then you can modify the values as per your
assignment. And during assignment order does not matter.
Am I right Frederick?

Oct 3 '06 #9

P: n/a
S S posted:
In case of member initialization via initialization list, you
initialize them in order which they are declared.

Yes. The order in which the appear in the initialisation list is of no
consequence.

Even if you do not give any initialization list (but you preferred
assignment), in this case also all members will be initialized default
in order which they are declared but after then you can modify the
values as per your assignment.

No, they are not initialised at all! Take the following code for instance:

int main()
{
int i;
}

The variable, "i", is _never_ initialised.

And now take the following example:

class MyClass {
int i;

public:

MyClass()
{
i = 5;
}
};

The member variable, "i", is _never_ initialised, not even default
initialised. If you would like to default-initialise it, you would have to
change the constructor's definition to:

MyClass() : i()
And during assignment order does not matter.

Once you're past the initialisation list and into the body of the
constructor, it's a whole different ball game. You're into the land of
normal code, where sequence points and so forth play a part.

Ask more questions if you'd like further clarification.

--

Frederick Gotham
Oct 3 '06 #10

P: n/a
S S

Frederick Gotham wrote:
S S posted:
In case of member initialization via initialization list, you
initialize them in order which they are declared.


Yes. The order in which the appear in the initialisation list is of no
consequence.

Even if you do not give any initialization list (but you preferred
assignment), in this case also all members will be initialized default
in order which they are declared but after then you can modify the
values as per your assignment.


No, they are not initialised at all! Take the following code for instance:

int main()
{
int i;
}

The variable, "i", is _never_ initialised.

And now take the following example:

class MyClass {
int i;

public:

MyClass()
{
i = 5;
}
};

The member variable, "i", is _never_ initialised, not even default
initialised. If you would like to default-initialise it, you would have to
change the constructor's definition to:

MyClass() : i()
You are right here. Actually I should have said that for built in
types, there is no gurantee that they will be initialized before they
are getting assigned. But for all others types my statement holds true.
>
And during assignment order does not matter.


Once you're past the initialisation list and into the body of the
constructor, it's a whole different ball game. You're into the land of
normal code, where sequence points and so forth play a part.

Ask more questions if you'd like further clarification.

--

Frederick Gotham
Oct 3 '06 #11

P: n/a
S S posted:
You are right here. Actually I should have said that for built in
types, there is no gurantee that they will be initialized before they
are getting assigned. But for all others types my statement holds true.

If by "all other types", you mean user-defined classes which have a non-
trivial constructor, then yes.

Here's an example of a non-built-in type which won't get any sort of
initialisation:

struct MyStruct { int i; };

int main() { MyStruct obj; }

The rule of thumb is as follows:

(1) Things don't get initialised ever... unless:

(1.a) You explicitly initialise them.
or
(1.b) They have an actual constructor written for them (known as a
"non-trivial constructor" in Standard terms.

--

Frederick Gotham
Oct 3 '06 #12

This discussion thread is closed

Replies have been disabled for this discussion.