The order of member initialization

A

asdf

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;}

};
 
P

Phlip

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.
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.
 
A

asdf

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;}
};
 
P

Phlip

[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!)]
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.
 
M

Mike Wahler

asdf said:
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
 
S

Salt_Peter

Please don't top post, its for your benefit.
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 ) { }
};
 
B

Bo Persson

asdf said:
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
 
F

Frederick Gotham

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".
 
S

S S

Frederick said:
asdf posted:



g++ issues a warning for this.




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".

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?
 
F

Frederick Gotham

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.
 
S

S S

Frederick said:
S S posted:



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




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.
 
F

Frederick Gotham

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.
 

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

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top