default constructor

T

t

Suppose class A has no programmer-written constructors and the
compiler generates a default constructor for it. Suppose class B is
exactly like class A except it has a programmer-written default
constructor with no initializer list and an empty body.

Do the default constructors of A and B act the same in all situations?
 
G

Gianni Mariani

t said:
Suppose class A has no programmer-written constructors and the
compiler generates a default constructor for it. Suppose class B is
exactly like class A except it has a programmer-written default
constructor with no initializer list and an empty body.

Do the default constructors of A and B act the same in all situations?

I think the default constructor you describe in B is pretty much the
same as the compiler supplied one in A so I can't think of any reasons
why it would behave differently from a standard compliance point of view.
 
J

James Kanze

I think the default constructor you describe in B is pretty
much the same as the compiler supplied one in A so I can't
think of any reasons why it would behave differently from a
standard compliance point of view.

There are some subtle differences when you use A() and B(), I
think. But the rules are changing, and I don't normally write
constructors which don't initialize everything, so I don't worry
about them too much. (I think that under the current rules, A()
will cause the equivalent of zero initialization, where as B()
will call the user defined constructor, which is a no-op. But I
wouldn't swear to it.)
 
A

Alf P. Steinbach

* James Kanze:
There are some subtle differences when you use A() and B(), I
think. But the rules are changing, and I don't normally write
constructors which don't initialize everything, so I don't worry
about them too much. (I think that under the current rules, A()
will cause the equivalent of zero initialization, where as B()
will call the user defined constructor, which is a no-op. But I
wouldn't swear to it.)

Consider:

struct A
{
double x;
};

struct B
{
double x;
B() {} // Oops, forgot to initialize x!
};

Then

A a = A(); // Very zeroed.

but

B b = B(); // Not zeroed, indeterminate value!

The usual terminology is a bit confusing, because while (I think) there
is such a beast as a generated copy constructor, there isn't really a
generated default constructor. Using A in a way that requires zeroing,
like above, doesn't magically introduce a generated default constructor
that also fixes the subsequent

// Local variable:
A a2; // Not zeroed!

However, the notion of a generated default constructor lets us (and the
standard, IIRC) talk about that constructor being called or invoked. It
can perhaps be reconciled by the additional notion that a generated
default constructor isn't necessarily called in every default
construction, or that it adjusts its behavior depending on the context
of its invocation. But that mental model starts showing similarity to
current physics, heaping exception upon exception to make it fit.

So, as much else in C++ it's extremely complicated, just in order to
support a micro-optimization -- leaving locals uninitialized /by
default/ -- that perhaps made sense 30 years ago but not today.

Cheers, & hth.,

- Alf
 
G

Gianni Mariani

Alf P. Steinbach wrote:
....
Then

A a = A(); // Very zeroed.

Right - for POD types.

I thought that held true only for POD types.

....
So, as much else in C++ it's extremely complicated, just in order to
support a micro-optimization -- leaving locals uninitialized /by
default/ -- that perhaps made sense 30 years ago but not today.

It may make less sense for a wide set of applications today compared to
what it did 20 years ago, however there is still a small but important
set of applications that these optimizations are significant.
 
A

Alf P. Steinbach

* Gianni Mariani:
Alf P. Steinbach wrote:
...

Right - for POD types.

I thought that held true only for POD types.

You thought correctly.

...

It may make less sense for a wide set of applications today compared to
what it did 20 years ago, however there is still a small but important
set of applications that these optimizations are significant.

Yes, but not as default.

It's the attempt to make it a default micro-optimization that introduces
complexity.


Cheers, & hth.,

- Alf
 
T

t

I have a lot of questions in mind, but this topic seems to be
complicated, so I will content myself with the following only.

1. Why does "A a = A();" initialize x to 0, but "A a;" doesn't in
local scope? Are you saying this is purposely designed so that the
programmer can choose not to initialize variables for the sake of
optimization?

2. What exactly is the difference between:

A a;

and

A a = A();

I always thought they were the same, but apparently not.
 
J

James Kanze

I have a lot of questions in mind, but this topic seems to be
complicated, so I will content myself with the following only.
1. Why does "A a = A();" initialize x to 0, but "A a;" doesn't in
local scope? Are you saying this is purposely designed so that the
programmer can choose not to initialize variables for the sake of
optimization?

I don't think it was intentional, per se. The idea is that if
you write A(), you get initialization, and otherwise you don't.
The problem with local scope is, of course, that "A a()" is not
a variable defintion, but a function declaration.
2. What exactly is the difference between:
and

A a = A();
I always thought they were the same, but apparently not.

Not really. In this case, the difference is just what I have
said; in one case, you get zero initialization, in the other
not. If there is a user defined constructor, they are both
identical. More generally, however:
A a( someInit ) ;
and
A a = someInit ;
are not identical. The first is direct initialization; the
compiler tries to find a constructor which can be called using
someInit. The second is copy initialization; the compiler tries
to *convert* someInit to A, and initializes the variable using
the copy constructor. (In fact, the compiler is allowed to
optimize out the use of the copy constructor, *provided* the
program would be legal if it didn't. If the constructor of A
which takes a someInit is explicit, for example, the second form
won't compile, or if the conversion of someInit to A requires
two user defined conversions.)
 

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
473,772
Messages
2,569,593
Members
45,108
Latest member
AlbertEste
Top