[comp.lang.c++] Bug in multiple inheritence

steve@lia (Stephen Williams) (01/12/91)

The following program demonstrates an apparent bug in C++ 2.0 and 2.1.
Am I seeing things?


class X { int x, y; };
class Y { int a, b; };
class Mess  : public X, public Y { int m; };


main()
{
	Mess m;
	Mess &n = m;

	X x = n;
	Y y = n;	// <---- C++ Error!!!!  In this case y should get the
		// Y part of n, but is instead getting the X part.
		// An offset is missing.


	X &xp = n;
	Y &yp = n;	// <---- Works.  In this case the correct code
			// is generated.
}

steve@lia (Stephen Williams) (01/18/91)

Let me remind you of my problem. ...

>The following program demonstrates an apparent bug in C++ 2.0 and 2.1.
>Am I seeing things?
>
>
>class X { int x, y; };
>class Y { int a, b; };
>class Mess  : public X, public Y { int m; };
>
>
>main()
>{
>	Mess m;
>	Mess &n = m;
>
>	X x = n;
>	Y y = n;	// <---- C++ Error!!!!  In this case y should get the
>		// Y part of n, but is instead getting the X part.
>		// An offset is missing.
>	X &xp = n;
>	Y &yp = n;	// <---- Works.  In this case the correct code
>			// is generated.
>}


ken@tucana.csis.dit.csiro.au respondes: 

>Isn't it unsafe anyway to assign a derived class instance to a base class
>instance?


I decided to check this out.  I searched the Ellis-Stroustrup C++ book
and found no mention either way about casting a derived INSTANCE to
a base class instance, but by experiment it seems that the AT&T compiler
does the assignment for single inheritence correctly, even to the point
of getting virtual functions right.  However, using the example above
and assuming that class X had a virtual function and Mess redefined
it, x.vfunc() would call X::vfunc(), whereas xp.vfunc() would call Mess::vfunc().
The problem in my test was that the compiler was inlining the virtual
functions for x.vfunc(), but not for xp.vfunc().

The moral:  although assignment of derived class instance to base
class instance is allowed by the compiler, it is probably illegal in the
language, and again I complain about the compiler.

Comments?

--Steve
steve@lia.com

steve@lia (Stephen Williams) (01/19/91)

In article <1991Jan17.190452.5204@lia> steve@lia.com (Stephen Williams) writes:
>The moral:  although assignment of derived class instance to base
>class instance is allowed by the compiler, it is probably illegal in the
>language, and again I complain about the compiler.
>

A co-worker pointed out to me page 297 of Ellis+Stroustrup:

	... objects of a derived class can be assigned to
	objects of a public base class.

I now believe that assignment of a derived class object to
a base class object is broken for multiple inheritence.  This
bug clearly shows up in SUN's 2.0 and 2.1(beta) C++ compiler.
Mail me if you want to see a sample program demonstrates
this bug.

--Steve Williams
steve@lia.com

mat@mole-end.UUCP (Mark A Terribile) (01/21/91)

> >The following program demonstrates an apparent bug in C++ 2.0 and 2.1.

> >class Mess  : public X, public Y { int m; };


> >	Mess m;
> >	Mess &n = m;

> >	X x = n;
> >	Y y = n;	// <---- C++ Error!!!!  In this case y should get the
> >		// Y part of n, but is instead getting the X part.
> >		// An offset is missing.

> ken@tucana.csis.dit.csiro.au respondes: 
 
> >Isn't it unsafe anyway to assign a derived class instance to a base class
> >instance?
 
> I decided to check this out.  I searched the Ellis-Stroustrup C++ book
> and found no mention either way about casting a derived INSTANCE to
> a base class instance, ...

??? But there's no cast.  In fact, that's legal.  In section 5.4, page 69,
we read (in commentary, I grant) that if it is legal to convert  Mess*  to  Y*
then it is legal to convert  Mess  to  Y& , and even to do so by cast:

		void f( X );
		void f( Y );

		Mess m;
		f( (Y&) m );	// Unambiguous: it will call  f( Y ) .

		     ... but by experiment it seems that the AT&T compiler
> does the assignment for single inheritence correctly, even to the point
> of getting virtual functions right.  However, using the example above and
> assuming that class X had a virtual function and Mess redefined it, x.vfunc()
> would call X::vfunc(), whereas xp.vfunc() would call Mess::vfunc().

What you have is a genuine bug.

> The problem in my test was that the compiler was inlining the virtual
> functions for x.vfunc(), but not for xp.vfunc().

A definite bug, actually.  The compiler is known to assume in dealing with
references that it is dealing with an exact type; it is not.
 
> The moral:  although assignment of derived class instance to base
> class instance is allowed by the compiler, it is probably illegal in the
> language, and again I complain about the compiler.
 
> Comments?

Well, yes.  It's quite legal.  See section 12.8 in the ARM, p 297 in the
hardcover.  It is made quite clear:  ``This implies ($12.3) that objects of
a derived class can be assigned to objects of a public base class. ...''

It is also noted in the commentary that this `slicing' may seem dangerous,
but that it is consistant with all the other rules of the language, and that
protections against probably would give a false confidence.
-- 

 (This man's opinions are his own.)
 From mole-end				Mark Terribile

jimad@microsoft.UUCP (Jim ADCOCK) (01/26/91)

In article <472@mole-end.UUCP> mat@mole-end.UUCP (Mark A Terribile) writes:
|It is also noted in the commentary that this `slicing' may seem dangerous,
|but that it is consistant with all the other rules of the language, and that
|protections against probably would give a false confidence.

Compiler writers would do well to issue a warning when "slicing" is 
performed on objects with virtual functions.  It *could be* that this
slicing is want the programmer wants.  But the probability would seem
to be vanishingly small.

mat@mole-end.UUCP (Mark A Terribile) (02/03/91)

> |It is also noted in the commentary that this `slicing' may seem dangerous,
> |but that it is consistant with all the other rules of the language, and that
> |protections against probably would give a false confidence.
 
> Compiler writers would do well to issue a warning when "slicing" is 
> performed on objects with virtual functions.  It *could be* that this
> slicing is want the programmer wants.  But the probability would seem
> to be vanishingly small.

I'm not so sure about that.  One of the things I'm trying to come to grips
with right now (actually, trying to write an essay on) is how classes that
play different parts, that have different sorts of roles, can expect to use
inheritance and virtualization differently, if at all.  Certainly, some of
the common examples (GUIs) used by those who teach Object Orientation can
stand slicing.  Many real-world problems cannot.  But probably some can.

Before we make such proclamations, I think we need to develop a set of
concepts to describe the purposes to which are put inheritance and
virtualization.
-- 

 (This man's opinions are his own.)
 From mole-end				Mark Terribile