brianl@wenti.Berkeley.EDU (Brian Lee) (08/02/90)
Many thanks to Brian Kennedy <bmk@dux.csc.ti.com> for kindly pointing out that my example in Article 8944 really does produce correct results. This is just another example of a computer doing what you told it to do instead of what you wanted it to do. :-) In my example, the default constructors for superclasses are called because my specification of the subclass copy constructor replaces the default component-wise initialization that would have been generated and by omission of explicit base initialization specifies that the default constructors should be used. For example, the classes 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"; } }; should really have been defined as 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& y) : X(y) { cout << "copy Y::Y(const Y&)\n"; } }; class Z : public Y { public: Z() { cout << "default Z::Z()\n"; } Z(const Z& z) : Y(z) { cout << "copy Z::Z(const Z&)\n"; } }; The revised definitions work fine. Sorry for any confusion this may have caused. Brian Lee
leo@atcmp.nl (Leo Willems) (08/03/90)
From article <26655@pasteur.Berkeley.EDU>, by brianl@wenti.Berkeley.EDU (Brian Lee): > Many thanks to Brian Kennedy <bmk@dux.csc.ti.com> for kindly > pointing out that my example in Article 8944 really does produce > correct results. This is just another example of a computer doing > what you told it to do instead of what you wanted it to do. :-) > That may be, but your answer and the replay from Brain Kennedy have taken away the focus from my original problem. Since everybody seems to be on the beach these days, here it is again. My question is simple: why does the following program generate a call to the default constructor from class A for variable 'copd'? (If this is not a bug in 2.1 (2.0 as well) try switching the declarations of a and b in class C; then A::A() is not called: if the previous one is NOT a bug then this one is!) ============ #include <stdio.h> class A{ public: A() { ida = 0; puts("default constructor A()"); } A(int i) {ida = i; puts("constructor A(int)"); } private: int ida; }; class B{ public: B() { idb = 0; puts("default constructor B()"); } B(B& b) { idb = b.idb; puts("copy constructor B(B&)"); } private: int idb; }; class C{ public: C(){ puts("default constructor C()");} protected: A a; //switch these: bug(?) gone B b; // if not a bug: A::A() gone!!!! }; main() { puts(" first a 'default' constructor:"); C defd; puts("\n now the copy constructor: "); C copd(defd); //suspicious A::A() class here } ======== Thanks in advance Leo
dsa@dlogics.COM (David Angulo) (08/08/90)
In article <643@atcmpe.atcmp.nl>, leo@atcmp.nl (Leo Willems) writes: > My question is simple: why does the following program generate a > call to the default constructor from class A for variable 'copd'? > > (If this is not a bug in 2.1 (2.0 as well) try switching the > declarations of a and b in class C; then A::A() is not called: if the > previous one is NOT a bug then this one is!) > > > ============ > > #include <stdio.h> > > class A{ > public: > A() { ida = 0; puts("default constructor A()"); } > A(int i) {ida = i; puts("constructor A(int)"); } > private: > int ida; > }; > > class B{ > public: > B() { idb = 0; puts("default constructor B()"); } > B(B& b) { idb = b.idb; puts("copy constructor B(B&)"); } > private: > int idb; > }; > > class C{ > public: > C(){ puts("default constructor C()");} > protected: > A a; //switch these: bug(?) gone > B b; // if not a bug: A::A() gone!!!! > }; > > main() > { > puts(" first a 'default' constructor:"); > C defd; > > puts("\n now the copy constructor: "); > > C copd(defd); //suspicious A::A() class here ^^^^ Well, I don't know how this compiled because you don't have anything other than a default constructor for class C. This shouldn't have compiled! > } > I hate this stupid program This is really stupid Who wrote this junk? -- David S. Angulo (312) 266-3134 Datalogics Internet: dsa@dlogics.com 441 W. Huron UUCP: ..!uunet!dlogics!dsa Chicago, Il. 60610 FAX: (312) 266-4473
mat@mole-end.UUCP (Mark A Terribile) (08/09/90)
> > My question is simple: why does the following program generate a > > call to the default constructor from class A for variable 'copd'? [ real query about something that might be a real bug, ending with ] > > class C{ > > public: > > C(){ puts("default constructor C()");} > > protected: > > A a; //switch these: bug(?) gone > > B b; // if not a bug: A::A() gone!!!! > > }; > > . . . > > C copd(defd); //suspicious A::A() class here > ^^^^ > Well, I don't know how this compiled because you don't have > anything other than a default constructor for class C. This > shouldn't have compiled! Except that copy constructors can be created by the compiler automatically, and any investigation into this matter should take them into account by declaring them private or else by declaring them public and providing them, appropriately studded with probes. It should compile (as far as I can see) and it did. Not to say that there might not be some interesting and subtle problems with it; I haven't got that compiler (which I presume to be cfront) handy, else I would check. If the original author would check out the copy constructors, I would like to hear of the results. [ A bunch of blank lines ] > I hate this stupid program And the Net should care? If you hate it, why bother to reply? Why bother to repost the whole thing? And if you are going to flame, please be right. Otherwise people like me will feel free to jump down your throat. ``And them's that don't like me can leave me alone.'' [ Another bunch of blank lines ] > This is really stupid Well, it's pretty clear that SOMETHING is at least a little stupid; I don't think that it's the original posting, however. There's something subtle going on in there. [ Yet another bunch of blank lines ] > Who wrote this junk? His name was on it, as I recall. I don't know that I can endorse the appellation `junk' for HIS work. > -- > David S. Angulo (312) 266-3134 > Datalogics Internet: dsa@dlogics.com > 441 W. Huron UUCP: ..!uunet!dlogics!dsa > Chicago, Il. 60610 FAX: (312) 266-4473 I hope that the author of the remarks was not the individual whose name appears in the signature; this wouldn't be the first case of a pirated account. The infamous Case of the Impersonation of Elizabeth Bimmler comes to mind. ``And then some deranged cat-molester begins posting about the role of contraception in the development of the ball-point pen.'' --The Hitch-Hiker's Guide To The Net -- (This man's opinions are his own.) From mole-end Mark Terribile
bmk@osage.csc.ti.com (Brian M Kennedy) (08/15/90)
In article <615@dlogics.COM>, dsa@dlogics.COM (David Angulo) writes: => =>In article <643@atcmpe.atcmp.nl>, leo@atcmp.nl (Leo Willems) writes: =>=> My question is simple: why does the following program generate a =>=> call to the default constructor from class A for variable 'copd'? =>=> =>=> (If this is not a bug in 2.1 (2.0 as well) try switching the =>=> declarations of a and b in class C; then A::A() is not called: if the =>=> previous one is NOT a bug then this one is!) =>=> =>=> #include <stdio.h> =>=> =>=> class A{ =>=> public: =>=> A() { ida = 0; puts("default constructor A()"); } =>=> A(int i) {ida = i; puts("constructor A(int)"); } =>=> private: =>=> int ida; =>=> }; =>=> =>=> class B{ =>=> public: =>=> B() { idb = 0; puts("default constructor B()"); } =>=> B(B& b) { idb = b.idb; puts("copy constructor B(B&)"); } =>=> private: =>=> int idb; =>=> }; =>=> =>=> class C{ =>=> public: =>=> C(){ puts("default constructor C()");} =>=> protected: =>=> A a; //switch these: bug(?) gone =>=> B b; // if not a bug: A::A() gone!!!! =>=> }; =>=> =>=> main() =>=> { =>=> puts(" first a 'default' constructor:"); =>=> C defd; =>=> =>=> puts("\n now the copy constructor: "); =>=> =>=> C copd(defd); //suspicious A::A() class here => ^^^^ => Well, I don't know how this compiled because you don't have => anything other than a default constructor for class C. This => shouldn't have compiled! => =>=> } =>=> In response to David, this should compile. A copy constructor is implicitly defined for every class unless a copy constructor is explicitly defined. In this case, the following declaration in class C is implicit: C (C&); (Note, it is not C (const C&) because C has a member B which has a copy constructor that does not accept a const argument. E&S p295) In response to Leo's question, which I will rephrase "Why does the implicit copy constructor generated for class C call the default constructor for class A? Is this a bug?": There are many statements in E&S which somewhat imply how an implicit copy constructor is implemented -- however, it is never spelled out. I believe Leo is assuming (a perfectly reasonable assumption) that it is implemented as: C (C& i) :a(i.a), b(i.b) {} where b(i.b) calls the user-defined copy constructor, and a(i.a) calls the implicit constructor A (A& i) :ida(i.ida) {} A look at the cfront 2.00.01 generated C shows that the implicit copy constructor is defined using the implicit memberwise assignment (or, at least, achieves a similar result): C (C& i) :a(), b(i.b) {<perform "bitwise" copy of i.a to a>} Is it a compiler bug? Only if the C++ language requires compilers to define copy constructors a certain way. I do not believe E&S does so. It does define exactly how copy constructors should be DECLARED and when they should be DEFINED, but it only hints at how it should be DEFINED. In fact, E&S (p295) hints that a compiler could do "bitwise" copying in the implicit copy constructors. Perhaps the ANSI spec should be more clear about this. So, as with any language or architecture spec, if the language definition does not define something, you should not assume that it is one way -- Murphy's law will see to it that you get burned ;-) In all but the simplest of the classes that I write, I always define both a default constructor and a copy constructor. Then I always know how it is defined (besides, it is next to trivial to write). Hope that helps. Disclaimer: I have made educated guesses -- only the ATT'ers can say for sure what cfront is trying to do here and whether or not it is a bug (i.e. unintended behavior). --------------------------------- Brian M. Kennedy <bmk@csc.ti.com> Computer Systems Laboratory Computer Science Center Texas Instruments Incorporated
rfg@NCD.COM (Ron Guilmette) (08/16/90)
In article <1990Aug14.190925.19166@csc.ti.com> bmk@osage.csc.ti.com (Brian M Kennedy) writes:
<...
<In response to Leo's question, which I will rephrase "Why does the implicit
<copy constructor generated for class C call the default constructor for class
<A? Is this a bug?":
<
<There are many statements in E&S which somewhat imply how an implicit copy
<constructor is implemented -- however, it is never spelled out. I believe
<Leo is assuming (a perfectly reasonable assumption) that it is implemented as:
<
< C (C& i) :a(i.a), b(i.b) {}
<
<where b(i.b) calls the user-defined copy constructor, and a(i.a) calls the
<implicit constructor
<
< A (A& i) :ida(i.ida) {}
<
<A look at the cfront 2.00.01 generated C shows that the implicit copy
<constructor is defined using the implicit memberwise assignment (or, at
<least, achieves a similar result):
<
< C (C& i) :a(), b(i.b) {<perform "bitwise" copy of i.a to a>}
<
<
<Is it a compiler bug? Only if the C++ language requires compilers to
<define copy constructors a certain way. I do not believe E&S does so.
<It does define exactly how copy constructors should be DECLARED and
<when they should be DEFINED, but it only hints at how it should be
<DEFINED. In fact, E&S (p295) hints that a compiler could do "bitwise"
<copying in the implicit copy constructors. Perhaps the ANSI spec should
<be more clear about this.
No. The ANSI standard should *DEFINITELY* be more clear about this!
Note that the same lack of specificity exists also for the definitions
of implicitly supplied (i.e. compiler generated) default constructors
and assignment operators.
--
// Ron Guilmette - C++ Entomologist
// Internet: rfg@ncd.com uucp: ...uunet!lupine!rfg
// Motto: If it sticks, force it. If it breaks, it needed replacing anyway.
jimad@microsoft.UUCP (Jim ADCOCK) (08/18/90)
In article <1990Aug14.190925.19166@csc.ti.com> bmk@osage.csc.ti.com (Brian M Kennedy) writes: >Is it a compiler bug? Only if the C++ language requires compilers to >define copy constructors a certain way. I do not believe E&S does so. >It does define exactly how copy constructors should be DECLARED and >when they should be DEFINED, but it only hints at how it should be >DEFINED. In fact, E&S (p295) hints that a compiler could do "bitwise" >copying in the implicit copy constructors. Perhaps the ANSI spec should >be more clear about this. Hm, I thought it was clear that E&S pg 295 was saying that a smart compiler could recognize when the results of a generated copy constructor would be identical to a bitwise copy, and just do the bitwise copy using an intrinsic. In any case, the small text annotation "hints" such as this one, do not constitute part of the text the ANSI-fication effort is working from.