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