mbl@lri.lri.fr (Lafon) (07/17/90)
Consider the following program; it defines a base class WIDGET and 2 derived classes PRIMITIVE and COMPOSITE. There is a WIDGET constructor that takes a COMPOSITE& as argument. This causes the problem: ---bug.cfront.C extern "C" { int printf (const char*, ...); } class COMPOSITE; class WIDGET { protected: int val; public: WIDGET (int); WIDGET (COMPOSITE&, int); #ifdef BUG WIDGET (WIDGET& w); #endif }; class COMPOSITE : public WIDGET { public: COMPOSITE (int); }; class PRIMITIVE : public WIDGET { public: PRIMITIVE (int); PRIMITIVE (COMPOSITE&, int); }; WIDGET :: WIDGET (int) { printf ("WIDGET :: WIDGET (int)\n"); } WIDGET :: WIDGET (COMPOSITE&, int) { printf ("WIDGET :: WIDGET (COMPOSITE&, int)\n"); } PRIMITIVE :: PRIMITIVE (int v) : (v) { printf ("PRIMITIVE :: PRIMITIVE (int)\n"); } PRIMITIVE :: PRIMITIVE (COMPOSITE& super, int v) // this is line 45 (see below) : (super, v) { printf ("PRIMITIVE :: PRIMITIVE (COMPOSITE&, int)\n"); } COMPOSITE :: COMPOSITE (int v) : (v) { printf ("COMPOSITE :: COMPOSITE (int)\n"); } main () { printf ("creating toplevel\n"); COMPOSITE toplevel (10); printf ("creating pushb\n"); PRIMITIVE pushb (toplevel, 20); printf ("done\n"); } ---end bug.cfront.C compile without -DBUG: ---------------------- sun3 % CC2 -o bug bug.cfront.C CC bug.cfront.C: 1>> "bug.cfront.C", line 45: warning: v not used cc -L /usr/local/lib/CC2 -o bug bug.cfront.c -lC sun3 % bug creating toplevel WIDGET :: WIDGET (int) COMPOSITE :: COMPOSITE (int) creating pushb 2>> PRIMITIVE :: PRIMITIVE (COMPOSITE&, int) done 1- the warning is erroneous 2- the constructor for PRIMITIVE does not call its base constructor -- going to the generated C code, it appears that PRIMITIVE (COMPOSITE& super, int v) generates * (WIDGET*) this = * (WIDGET*) super; instead of calling WIDGET::WIDGET (super, v); !! compile with -DBUG: (this defines a copy constructor for WIDGET) ------------------- sun3 % CC2 -DBUG -o bug bug.cfront.C CC bug.cfront.C: cc -L /usr/local/lib/CC2 -o bug bug.cfront.c -lC sun3 % bug creating toplevel WIDGET :: WIDGET (int) COMPOSITE :: COMPOSITE (int) creating pushb >> WIDGET :: WIDGET (COMPOSITE&, int) >> PRIMITIVE :: PRIMITIVE (COMPOSITE&, int) done - the warning has disappeared - now everything is fine, although the copy constructor WIDGET(WIDGET&) is not called (its body is not defined) It looks to me that there is a copy constructor weirdness. Somehow, cfront gets confused by WIDGET :: WIDGET (COMPOSITE&, int), because COMPOSITE derives from WIDGET. If COMPOSITE is independant from WIDGET, there is no problem at all. Maybe this is fixed in 2.1 ? [note: this works perfectly well with g++] ___ 0 Michel Beaudouin-Lafon uucp : mbl@lri.lri.fr / \ / LRI - Bat 490 bitnet: mbl@FRLRI61.bitnet / __/ / Universite de Paris-Sud voice : +33 (1) 69 41 69 10 /__ \/ F-91405 ORSAY Cedex +33 (1) 69 41 66 29