[comp.lang.c++] problem with ** and *&

mfx@cs.tu-berlin.de (Markus Freericks) (06/08/91)

I have a problem with either my AT&TC++ Rel2.1 or my understanding of C++ (:-)
suppose two classes and a function

class a { };
class b : public a { };

int fpp(a** x){  return 42; }

main(){
  b* bptr=new b();
  fpp(&bptr);
}

now, my CC sez
	error: bad argument  1 type for fpp(): b ** ( a ** expected)
why this ?
if a 'b' can be used in the same places as an 'a' and a pointer to b can
be used as a pointer to a; why doesn't this hold for a pointer to a
pointer to b??

I got into this problem when trying to write a function

int fpp(a*&x){  return 42; }

main(){
  b* bptr=new b();
  fpp(bptr);
}

to which the compiler said
	warning: temporary used to initialize reference; 
	no changes will be propagated to actual argument

Thats really a funny one: the compiler knows that I probably want to
change the argument (otherwise the function wouldn't take a reference,
right?), but is somehow unable or unwilling to generate code that
does this!

Are these just problems of the implementation or do I suffer from
some misunderstanding?

Markus Freericks
--
Markus Freericks	phone: +49-30-4034110	
Oranienburger Str. 142	email: mfx@opal.cs.tu-berlin.de	
1000 Berlin 26 FRG	or mfx%tubopal@DB0TUI11.BITNET	

pete@borland.com (Pete Becker) (06/09/91)

In article <MFX.91Jun8150513@kit.cs.tu-berlin.de> mfx@cs.tu-berlin.de (Markus Freericks) writes:
>if a 'b' can be used in the same places as an 'a' and a pointer to b can
>be used as a pointer to a; why doesn't this hold for a pointer to a
>pointer to b??

	The short answer is that the language defines a conversion from a
class to one of its public bases, and a conversion of a pointer to a class
to a pointer to one of its public bases, but does not do so for pointers to
pointers to classes.  So it just isn't allowed.
	Of course, the next question is, why isn't it allowed?  Basically,
because it would be very dangerous.  For example:

	void func( Base **handle )
	{
	*handle = new Base;
	}

	Derived *d;
	func( &d );

	Now 'd' has been declared to be a pointer to Derived, but is, in fact,
a pointer to Base.  The compiler doesn't know this, though, and will be 
perfectly happy compiling code that applies member functions of Derived to
the data pointed to by 'd'.  Even calling virtual functions that don't exist
in Base, which will almost certainly crash the program.
	There may occasionally be times where you know for sure that such a
call is safe, and if one of those arises you can use a cast to tell the
compiler that you are taking responsibility for any ill effects that may

ark@alice.att.com (Andrew Koenig) (06/10/91)

In article <MFX.91Jun8150513@kit.cs.tu-berlin.de> mfx@cs.tu-berlin.de (Markus Freericks) writes:

> if a 'b' can be used in the same places as an 'a' and a pointer to b can
> be used as a pointer to a; why doesn't this hold for a pointer to a
> pointer to b??

Because you could break the type system if it did.  For example:

	class A { /* stuff */ };
	class B: public A { /* other stuff */ };

	main()
	{
		A a;
		B* bp;
		A** app;

		// Suppose this were legal...
		app = &bp;

		// Then we could do this:
		*app = &a;

		// which would make bp point at "a".  Then...

		B b;
		*bp = b;	// Oops!  We've clobbered memory
	}

There are many slippery issues having to do with pointer conversions
of this kind.  Designing a workable type system is not easy.
-- 
				--Andrew Koenig
				  ark@europa.att.com