About member variable initilization and default constructor issues

J

JosephLee

In Inside C++ object Model, Lippman said there are four cases in which
compile will sythesize a default constructor to initialize the member
variables if the constructor is absent:

1. there is a virtual function;

2. virtual inheritance;

3.base class with explicit default constructor;

4.member object with explicit default constructor.

e.g.

class A {

public:

int i;

A* p;
}
int main()
{
A a;
if(a.i ==0 || a.p == 0) //do something
}

The behavior is undefined for the above case. If we modify class A to
have any one of the four characeristics, then the member variables
will be initialized in the default constructor sythesysized by the
compiler, as though
A():i(0),p(0){} is defined in the class.

But I try this in different compilers, and yield different results. My
question is : Is Lippman teaching ISO standard, or compiler-
dependent? Thanks
 
V

Victor Bazarov

JosephLee said:
In Inside C++ object Model, Lippman said there are four cases in which
compile will sythesize a default constructor to initialize the member
variables if the constructor is absent:

1. there is a virtual function;

2. virtual inheritance;

3.base class with explicit default constructor;

4.member object with explicit default constructor.

e.g.

class A {

public:

int i;

A* p;
}
int main()
{
A a;
if(a.i ==0 || a.p == 0) //do something
}

The behavior is undefined for the above case. If we modify class A to
have any one of the four characeristics, then the member variables
will be initialized in the default constructor sythesysized by the
compiler, as though
A():i(0),p(0){} is defined in the class.

But I try this in different compilers, and yield different results. My
question is : Is Lippman teaching ISO standard, or compiler-
dependent? Thanks

The Standard says that the constructor is trivial if it's implicitly
defined and the class no virtual functions or virtual bases, all direct
base classes have trivial c-tors, all non-static data members also have
trivial c-tors. So, turn that around and you get what Lippman says.

V
 
M

Markus Moll

Hi

Victor said:
JosephLee said:
In Inside C++ object Model, Lippman said there are four cases in which
compile will sythesize a default constructor to initialize the member
variables if the constructor is absent:

1. there is a virtual function;

2. virtual inheritance;

3.base class with explicit default constructor;

4.member object with explicit default constructor. [...]
If we modify class A to
have any one of the four characeristics, then the member variables
will be initialized in the default constructor sythesysized by the
compiler, as though
A():i(0),p(0){} is defined in the class.

The Standard says that the constructor is trivial if it's implicitly
defined and the class no virtual functions or virtual bases, all direct
base classes have trivial c-tors, all non-static data members also have
trivial c-tors. So, turn that around and you get what Lippman says.

I disagree. Firstly, it's not correct that if 1-4 is not satisfied then
there will be no default-constructor synthesized:

"If there is no user-declared constructor for class X, a default constructor
is implicitly declared."

"An implicitly-declared default constructor for a class is implicitly
defined when it is used to create an object of its class type. The
implicitly-defined default constructor performs the set of initializations
of the class that would be performed by a user-written default constructor
for that class with an empty mem-initializer-list and an empty function
body"

Secondly, the latter phrase explains that in both of the above cases, the
program will behave as if there was a user-defined constructor

A() {}

This means that neither i nor p will be initialized.

Markus
 
V

Victor Bazarov

Markus said:
Hi

Victor said:
JosephLee said:
In Inside C++ object Model, Lippman said there are four cases in
which compile will sythesize a default constructor to initialize
the member variables if the constructor is absent:

1. there is a virtual function;

2. virtual inheritance;

3.base class with explicit default constructor;

4.member object with explicit default constructor. [...]
If we modify class A to
have any one of the four characeristics, then the member variables
will be initialized in the default constructor sythesysized by the
compiler, as though
A():i(0),p(0){} is defined in the class.

The Standard says that the constructor is trivial if it's implicitly
defined and the class no virtual functions or virtual bases, all
direct base classes have trivial c-tors, all non-static data members
also have trivial c-tors. So, turn that around and you get what
Lippman says.

I disagree. Firstly, it's not correct that if 1-4 is not satisfied
then there will be no default-constructor synthesized:

"If there is no user-declared constructor for class X, a default
constructor is implicitly declared."

"An implicitly-declared default constructor for a class is implicitly
defined when it is used to create an object of its class type. The
implicitly-defined default constructor performs the set of
initializations of the class that would be performed by a
user-written default constructor for that class with an empty
mem-initializer-list and an empty function body"

Secondly, the latter phrase explains that in both of the above cases,
the program will behave as if there was a user-defined constructor

A() {}

This means that neither i nor p will be initialized.

Right. I am not sure with whom you're arguing. The four specific
traits that cause an implicitly defined non-trivial c-tor in the
class are the same as in the Standard. Lippman says that the c-tor
is generated if any of the four is present. The Stadard says that
the c-tor is trivial if none of the four is present. In that sense
Lippman teaches the Standard. No?

V
 
M

Markus Moll

Hi

Victor said:
Right. I am not sure with whom you're arguing. The four specific
traits that cause an implicitly defined non-trivial c-tor in the
class are the same as in the Standard. Lippman says that the c-tor
is generated if any of the four is present. The Stadard says that
the c-tor is trivial if none of the four is present. In that sense
Lippman teaches the Standard. No?

1. I fail to see where it says that to say a constructor is trivial is the
same as to say that it isn't generated.
2. I disagree with the original claim that e.g. for a class like:

struct A
{
virtual void dummy() {} // virtual function present
int i;
A *p;
};

the compiler would generate a constructor as if A() : i(0), p(0) {}

Okay. 1 doesn't make any difference, because it wouldn't be observable
anyway. But 2 is simply wrong. Or am I?

Markus
 
V

Victor Bazarov

Markus said:
Hi



1. I fail to see where it says that to say a constructor is trivial
is the same as to say that it isn't generated.

Where *what* says that? The standard? The book?

An implicitly declared default c-tor is implicitly defined for a class.
There seems to be no clear connection between the terms "non-trivial"
and "implicitly defined". "Trivial" is used to define the lifetime of
objects and the behaviour of 'delete', for example. "Implicitly
defined" sets forth certain relation between the type and its bases and
members (bases should have their implicitly declared c-tors implicitly
defined if this class has its c-tor implicitly defined).

However, it's every author's right to draw parallels or make guesses as
to what the Standard actually means. Considering that Lippman is one
of the authorities in C++, he probably knows what he's talking about if
from his text it seems apparent that "non-trivial" and "implicitly
defined" and "generated" all mean basically the same thing.
2. I disagree with the original claim that e.g. for a class like:

struct A
{
virtual void dummy() {} // virtual function present
int i;
A *p;
};

the compiler would generate a constructor as if A() : i(0), p(0) {}

OK. I thought you disagreed with something I posted since you replied
to my post and not to the one you disagreed with.
Okay. 1 doesn't make any difference, because it wouldn't be observable
anyway. But 2 is simply wrong. Or am I?

As I can see, you quoted part of the Standard that explains that it is
incorrect to expect zero-initialisation of POD members by the implicitly
defined constructor. I agree.

V
 
M

Markus Moll

Hi

Victor said:
Where *what* says that? The standard? The book?

The standard, preferably.

Sorry... there seems to be more confusion than I thought :)

First: I have no idea about the book. I only know what JosephLee posted.
His original posting reads (excerpt):
In Inside C++ object Model, Lippman said there are four cases in which
compile will sythesize a default constructor to initialize the member
variables if the constructor is absent:
[Cases follow]

You replied:
The Standard says that the constructor is trivial if [...]
 So, turn that around and you get what Lippman says.

I had the impression that you were talking about different things. JosephLee
about when the default constructor would be provided by the compiler, you
about when it would be trivial.

If we modify class A to have any one of the four characeristics, then the
member variables will be initialized in the default constructor
sythesysized by the compiler, as though A():i(0),p(0){} is defined in the
class.

Which I still think is wrong, and apparently you agree with my reasoning
(see below). That was everything I wanted to express.
However, it's every author's right to draw parallels or make guesses as
to what the Standard actually means.

Sure. As I said, I don't know anything about the book, so I can't say what
parallels the author draws.
Considering that Lippman is one of the authorities in C++, he probably
knows what he's talking about if from his text it seems apparent
that "non-trivial" and "implicitly defined" and "generated" all mean
basically the same thing.

Huh? Proof by authority? That comes right after proof by assertion. ;-)
OK. I thought you disagreed with something I posted since you replied
to my post and not to the one you disagreed with.

Well... I disagreed with your agreeing with the original post... oh...
well...
As I can see, you quoted part of the Standard that explains that it is
incorrect to expect zero-initialisation of POD members by the implicitly
defined constructor. I agree.

Good. But you seemed to also agree when JosephLee stated the opposite.

Sorry, I'm really starting to get confused...

Markus
 
J

James Kanze

In Inside C++ object Model, Lippman said there are four cases in which
compile will sythesize a default constructor to initialize the member
variables if the constructor is absent:

Note that Lippman is talking about the internals of a C++
compiler, not about the language specification. According to
the language specification, a default constructor is always
synthesized if there is no user defined constructor. The
conditions below define what the standard calls a "trivial"
constructor (or rather the inverse); if the constructor is
"trivial", it's a no-op, and internally, the compiler doesn't do
anything.
1. there is a virtual function;
2. virtual inheritance;
3.base class with explicit default constructor;
4.member object with explicit default constructor.

That should be member object or base class with non-trivial
constructor.

And of course, the compiler doesn't even consider synthesizing a
default constructor if you have declared any other constructor.
class A {
public:
int i;
A* p;
}
int main()
{
A a;
if(a.i ==0 || a.p == 0) //do something
}
The behavior is undefined for the above case.
Yes.

If we modify class A to
have any one of the four characeristics, then the member variables
will be initialized in the default constructor sythesysized by the
compiler, as though
A():i(0),p(0){} is defined in the class.

No. The synthesized constructor doesn't initialize int's or
pointers.
But I try this in different compilers, and yield different
results. My question is : Is Lippman teaching ISO standard, or
compiler-dependent?

Well, he's talking about compiler internals, so it's definitely
implementation specific. But I'm rather surprised that he says
that the synthesized constructor will initialize the variables
above; the standard doesn't require it, and none of the
compilers on which Lippman has worked do it.
 
J

James Kanze

Note that the word in the book is "synthesized", not
"generated". But I think the difference is more one of context;
the book is talking about what the compiler does: in the case of
a trivial constructor, the compiler doesn't do anything. From a
language point of view, there is a constructor, but it doesn't
result in any code, which is what Lippman is talking about.
Where *what* says that? The standard? The book?
An implicitly declared default c-tor is implicitly defined for
a class. There seems to be no clear connection between the
terms "non-trivial" and "implicitly defined".

It seems very clear to me: if the class meets certain criteria,
the implicitly defined constructor is trivial. By definition,
no explicitly defined constructor (even one with an empty inline
body) is trivial. The set of all trivial constructors is a
subset of the set of all implicitly defined constructors.
"Trivial" is used to define the lifetime of
objects and the behaviour of 'delete', for example.

Trivial has nothing to do with the lifetime of objects. It is a
categoristic of default constructors, copy constructors, copy
assignment operators and destructors. Whether are trivial
authorizes some other operations: they all must be trivial, for
example, if the type is to be a member of a union.

Triviality is relevant to lifetime only in so far that if the
constructor is trivial, lifetime of the object is considered to
start as soon as the memory for it is allocated, and if the
destructor is trivial, lifetime of the object is considered to
last until the memory is freed or reused.
"Implicitly defined" sets forth certain relation between the
type and its bases and members (bases should have their
implicitly declared c-tors implicitly defined if this class
has its c-tor implicitly defined).

I don't think so. A special member function is implicitly
defined if it is implicitly declared and is used. It is
implicitly declared if the user hasn't explicitly declared it,
and in the case of a default constructor, if the user hasn't
explicitly declared any other constructor.
However, it's every author's right to draw parallels or make
guesses as to what the Standard actually means. Considering
that Lippman is one of the authorities in C++, he probably
knows what he's talking about if from his text it seems
apparent that "non-trivial" and "implicitly defined" and
"generated" all mean basically the same thing.

Actually, the quoted text is a lot more precise than that. It
speaks of when the compiler "synthesizes" a default constructor.
The standard never uses the word "synthesize", and from the name
of the book, I'm pretty sure the Lippman is talking about
compiler internals here---when does the compiler generate code
on its own for the constructor.

The answer is, of course, whenever the constructor is implicitly
declared, is used, and is not trivial. The definition of
"trivial", in the standard, is designed intentionally so that
the compiler implementation can do nothing in the case of a
trivial default constructor or a trivial destructor, and can do
a bitwise copy in the case of a trivial copy constructor or a
trivial assignment operator.

I disagree with his disagreement. A compiler very well could
generate the constructor like this. It's not required, however,
and none that I use do.
OK. I thought you disagreed with something I posted since you
replied to my post and not to the one you disagreed with.
As I can see, you quoted part of the Standard that explains
that it is incorrect to expect zero-initialisation of POD
members by the implicitly defined constructor. I agree.

It is, in fact, undefined behavior if you even read the values
(except if you read them as a character type).
 
J

James Kanze

The standard, preferably.
Sorry... there seems to be more confusion than I thought :)
First: I have no idea about the book. I only know what
JosephLee posted. His original posting reads (excerpt):
[Cases follow]
You replied:
The Standard says that the constructor is trivial if [...]
So, turn that around and you get what Lippman says.
I had the impression that you were talking about different things.

He is, in a way. Victor is talking about what the standard
says, using the terminology used in the standard. Lippman is
talking about what a compiler does, using a terminology which is
not that of the standard (possibly intentionally, to avoid the
risk of confusion). Two completely different things... except
that the authors of the standard weren't totally ignorant about
how compilers work---the wording in the standard concerning
"trivial" default constructors is intentially designed to
specify the case where the "generated" constructor is a no-op,
i.e. where the compiler doesn't need to "synthesize" anything.
JosephLee about when the default constructor would be provided
by the compiler, you about when it would be trivial.

No he didn't. JosephLee was also comparing different cases
where the compiler provided the constructor: he was comparing
the case where the constructor was trivial (the compiler didn't
have to synthesize anything) to when it wasn't (the compiler had
to generate code, even though you hadn't written any). The
question concerned the required behavior of the synthesized code
(and I'm pretty sure that JosephLee misunderstood what Lippman
wrote---Lippman was, along with Stroustrup, one of the lead
authors of CFront; I've used that compiler, and it doesn't
behave as JosephLee seems to think Lippman says it should).
Furthermore, JosephLee originally wrote:
Which I still think is wrong, and apparently you agree with my
reasoning (see below).

It's wrong, we all agree that it's wrong, and I'm almost sure
that Lippman didn't write anything else.

[...]
Huh? Proof by authority? That comes right after proof by
assertion. ;-)

Yes and no. The fact that Lippman has actually written C++
compilers would suggest very strongly that he knows something
about C++, and that his discussions concerning compiler
internals aren't too far off base. To the point where I'd
assume that JosephLee has misunderstood him.

In context, of course, it also seems probable that he is using
the word "sythesysize" to refer to what the compiler does,
internally. If I understand correctly, that's the whole point
of his book: what does the compiler do with the source code you
feed it?
Well... I disagreed with your agreeing with the original
post... oh... well...

Victor didn't agree with the original post. He agreed with what
Lippman said.
 
M

Markus Moll

Hi

James said:
The question concerned the required behavior of the synthesized code
(and I'm pretty sure that JosephLee misunderstood what Lippman
wrote---Lippman was, along with Stroustrup, one of the lead
authors of CFront; I've used that compiler, and it doesn't
behave as JosephLee seems to think Lippman says it should).

Well, as I said. Neither do I really know who Lippman is nor have I read his
books. So I _couldn't possibly_ disagree with Lippman, but just with
JosephLee's statements/conclusions. ;-)
It's wrong, we all agree that it's wrong, and I'm almost sure
that Lippman didn't write anything else.

Again: I was only referring to JosephLee's post. :)
In context, of course, it also seems probable that he is using
the word "sythesysize" to refer to what the compiler does,
internally. If I understand correctly, that's the whole point
of his book: what does the compiler do with the source code you
feed it?

I don't know the book, so I couldn't say what it's about.
Victor didn't agree with the original post. He agreed with what
Lippman said.

Okay. So my final words in this thread will be:

I was talking of something else and apparently I misunderstood what Victor
Bazarov said.

Hope that sorts it out :)

Markus
 

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,982
Messages
2,570,190
Members
46,740
Latest member
AdolphBig6

Latest Threads

Top