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