About initializing non-local object

J

James Kanze

Still having question about this. I have try this:
class A {
public:
A(const A& a, const std::string& name) { cout << name << endl; }
};
And got no compilation error. In this case, what is the
behaviour ? is it well defined ?

It's defined behavior, but unspecified: both variables will
first be zero initialized, then one of the variable's
constructors will be called, then the other one. The first
constructor will see a zero initialized A const&.

You might try it, adding something to A so that you can see the
initialization, say:

class A
{
public:
A( A const& other, std::string const& name )
: myFirst( 1 )
, mySecond( other.myFirst )
{
std::cout << name << std::endl ;
}
int myFirst ;
int mySecond ;
} ;

Use this in the two files above, and try linking them in
different orders. After initialization, both objects will have
myFirst == 1, but one of them will have mySecond == 1, the other
== 0. Which one is not specified, but with most compilers,
you'll find that it will depend on the order the object files
are incorporated into the build. (In an unspecified way; you
can't reliably use this for controlling order of initialization,
even unportably.)
 
R

Rolf Magnus

WaterWalk said:
I thought the object is initialized "normally" with that all members
zero.

What does "zero" mean for a non-pod?
Thus it can be used like a normal object(calling member
functions, etc).

You probably can't do that anyway. Think e.g. what happens if you write to
an std::string member before it got properly initialzied? You don't even
know what happens then. It might well lead to a derefrenced null pointer as
an example.
 
W

WaterWalk

It's defined behavior, but unspecified: both variables will
first be zero initialized, then one of the variable's
constructors will be called, then the other one. The first
constructor will see a zero initialized A const&.

You might try it, adding something to A so that you can see the
initialization, say:

class A
{
public:
A( A const& other, std::string const& name )
: myFirst( 1 )
, mySecond( other.myFirst )
{
std::cout << name << std::endl ;
}
int myFirst ;
int mySecond ;
} ;

Use this in the two files above, and try linking them in
different orders. After initialization, both objects will have
myFirst == 1, but one of them will have mySecond == 1, the other
== 0. Which one is not specified, but with most compilers,
you'll find that it will depend on the order the object files
are incorporated into the build. (In an unspecified way; you
can't reliably use this for controlling order of initialization,
even unportably.)

--
James Kanze (GABI Software) email:[email protected]
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Won't this cause possible indefinite recursive call of A's
constructor? If a1 and a2 are initialized after main executes and a1
is first used, according to the standard, they must be initialized
before their first use, so a1 shall be initialized. When initializing
a1, its constructor will use a2. Then a2 shall also be initialized.
But when initializing a2, a1 is required to be initialized. And so on.
 
J

James Kanze

Won't this cause possible indefinite recursive call of A's
constructor? If a1 and a2 are initialized after main executes

They can't be, because...
and a1
is first used, according to the standard, they must be initialized
before their first use, so a1 shall be initialized. When initializing
a1, its constructor will use a2. Then a2 shall also be initialized.
But when initializing a2, a1 is required to be initialized. And so on.

Exactly. The standard talks about this case, but then places
such restrictions on it as to make it impossible to implement in
practice. So you can, in practice, suppose that all static data
has been initialized before entering main.

(Obviously, if dynamic loading is involved, this may not be the
case. And that was, I believe, the motivation for the
"initialization after main" text. But the standard doesn't
really address dynamic loading, and in a very real sense, as far
as the standard is concerned, as soon as you call dlopen, or
it's Window's equivalent, you have undefined behavior.)
 
W

WaterWalk

They can't be, because...


Exactly. The standard talks about this case, but then places
such restrictions on it as to make it impossible to implement in
practice. So you can, in practice, suppose that all static data
has been initialized before entering main.

(Obviously, if dynamic loading is involved, this may not be the
case. And that was, I believe, the motivation for the
"initialization after main" text. But the standard doesn't
really address dynamic loading, and in a very real sense, as far
as the standard is concerned, as soon as you call dlopen, or
it's Window's equivalent, you have undefined behavior.)

--
James Kanze (GABI Software) email:[email protected]
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

I see. It's just like other initialization examples presented in
earlier posts, for example the "x1 = x2; x2 = x1;" thing.

BTW all those rules about initialization are really complicated. I
never thought it goes to such extremes.
 
A

Andrew Koenig

Yes, it is. But then I can just wonder why they changed that part of the
text.

I proposed the change, and I did so in part because I don't know what it
means to initialize an object's storage. Does it mean the same as using
memset to set the bytes that constitute the object's raw memory to zero? If
so, what if you're on a machine on which initializing an object that way
sets it to a value other than zero?

One of the changes between the 1998 and 2003 versions of the standard was to
clean up how initialization works. For example:

struct X {
int a;
std::string b;
};

struct Y {
int a;
int b;
};

In the 1998 standard, X().a is undefined; in the 2003 standard, it is
zero--even though Y().a is zero in both versions of the standard.
 

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
474,173
Messages
2,570,937
Members
47,481
Latest member
ElviraDoug

Latest Threads

Top