[comp.lang.c++] Default constructor, unexpected call

leo@atcmp.nl (Leo Willems) (07/16/90)

The next question was in comp.lang.c++ before, but is repeated since
I think it never reached the `world':


The next program calls a default constructor at an unexpected place, 
I think it is a bug.

=================
struct A{
	A(){ puts("I am default constructor A()"); }
};
	
struct B{
	B() { puts("I am default constructor B()"); }
	B(B&){  puts("I am copy constructor B(B&)"); }
};

struct C{
	C(){ puts("I am default constructor C()");}
	A a;
	B b;
};

main()
{
	puts(" first a 'default' constructor:");
	C defc;

	puts("\n now a  copy constructor: ");
	C copc(defc);
}

======outputs:  (after compilation with Glsp. 2.0 for sparc station):
 first a 'default' constructor:
I am default constructor A()
I am default constructor B()
I am default constructor C()

 now a  copy constructor: 
I am default constructor A()		<===== offending constructor call
I am copy constructor B(B&)
===============================

This is the first reason why I think this is a bug:
The A() constructor is used on the A part of variable copc,( not on
some temporary) so the A part of copc is first initialised using
A::A(), THEN overwitten using the default memberwise initialisation.
(In practice, this will not often lead to an error)

This is the second reason why I think this is a bug:
When in class C the declarations of the members A and B are switched
the `error' is gone, the output becomes:
================
 first a 'default' constructor:
I am default constructor B()
I am default constructor A()
I am default constructor C()

 now a  copy constructor: 
I am copy constructor B(B&)
===============
 
Is this fixed in 2.1? (If it's a bug......)

Thanks

Leo


 Leo Willems			Internet: leo@atcmp.nl
 AT Computing			UUCP:     mcsun!hp4nl!kunivv1!atcmpe!leo
 P. O. Box 1428				
 6501 BK  Nijmegen		Phone:    +31-80-566880
 The Netherlands		Fax:	  +31-80-555887

brianl@wenti.Berkeley.EDU (Brian Lee) (07/31/90)

In Article 8713, leo@atcmp.nl (Leo  Willems) describes how
the default constructor for a member class is sometimes called
instead of the copy constructor.  I am also using AT&T C++
Release 2.0, and a similar thing happens for base classes.  I'm
relatively new to this newsgroup, so please forgive me if this
is old news.

Consider the following program

#include <iostream.h>

class X {
public:
    X()         { cout << "default X::X()\n"; }
    X(const X&) { cout << "copy X::X(const X&)\n"; }};

class Y : public X {
public:
    Y()         { cout << "default Y::Y()\n"; }
//    Y(const Y&)       { cout << "copy Y::Y(const Y&)\n"; }
};

class Z : public Y {
public:
    Z()         { cout << "default Z::Z()\n"; }
    Z(const Z&) { cout << "copy Z::Z(const Z&)\n"; }
};

main()
{
    cout << "\ndefault:\n";
    Z k;
    cout << "\ncopy:\n";
    Z l = k;
}

It produces the following output

default:
default X::X()
default Y::Y()
default Z::Z()

copy:
default X::X()
default Y::Y()
copy Z::Z(const Z&)

Note that the default constructor for Y is called instead of a
copy constructor being generated and that calling the default 
constructor for Y causes the default constructor for X to be called
instead of the copy constructor for X.

Assuming that the semantics of member-wise initialization extend
to base class initialization, this is wrong.

Try increasing the length of the inheritance chain and/or playing
with different combinations of defined/undefined copy constructors.

It appears that to be safe, one should define a default and copy
constructor for all classes.

    Brian Lee
    U.C. Berkeley Cadgroup
    brianl@ic.Berkely.EDU