Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!uwm.edu!zaphod.mps.ohio-state.edu!tut.cis.ohio-state.edu!att!dptg!ulysses!andante!alice!shopiro From: shopiro@alice.UUCP (Jonathan Shopiro) Newsgroups: comp.lang.c++ Subject: Re: Chameleon objects (calling virtual functions from constructors) Summary: Some function pointer types have to be incompatible Keywords: virtual functions, constructor functions Message-ID: <10312@alice.UUCP> Date: 5 Jan 90 19:11:06 GMT References: <11266@csli.Stanford.EDU> <47479d37.12160@espol> <1727@osc.COM> <64@espol.decvax.UUCP> Organization: AT&T Bell Laboratories, Murray Hill NJ Lines: 52 In article <64@espol.decvax.UUCP>, roger@decvax.UUCP (Roger H. Scott) writes: > In article <1727@osc.COM> strick@osc.com (henry strickland) writes: > >In article <47479d37.12160@espol> roger@procase.UUCP (Roger H. Scott) writes: > >> > >>[Digression #2 - for Language Lawyers only] > >>"Derived *(*)()" [pointer to function returning pointer to Derived] > >>should be type compatible with "Base *(*)()" [pointer to function > >>returning pointer to Base]. These types were compatible in 1.2. > > > >In 1.2 you did get away with this, because there were no > >multiply inherited bases buried within an object -- all the > >bases overlaid each other, starting at the same address. > > > >... class Base { int b; }; class Other { int o; }; class Derived : public Other, public Base { int d; }; Derived x; // Aren't these typedefs easier to read than what you wrote? typedef Base* FPBase(); typedef Derived* FPDerived(); Base* BaseOfX() { return &x; } Derived* DerivedOfX() { return &x; } void func() { FPBase* f = &BaseOfX; // okay FPDerived* g = &DerivedOfX; // okay Base* mumble = (*f)(); // okay Base* fleezle = (*g)(); // works okay, takes care of offset // compare the generated code with the previous // If I remember correctly, this is what you'd like to be able to do. f = &DerivedOfX; // or even harder ... f = g; // While this is apparently type-safe, the compiler can't do it because // FPBase and FPDerived are used differently, as the above example shows. // The only way this could be done is for the compiler to lay down a little // function that did the offset adjustment and then use the address of // that. The first assignment to f could be done with a hidden static // function, but for the second assignment it would be much harder // (suppose the value of g changes later, suppose func is called // recursively). } -- Jonathan Shopiro AT&T Bell Laboratories, Warren, NJ 07060-0908 research!shopiro (201) 580-4229