Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!mips!dimacs.rutgers.edu!morley.rutgers.edu!purtill From: purtill@morley.rutgers.edu (Mark Purtill) Newsgroups: comp.lang.c++ Subject: Re: For Philosophers and Lawyers Message-ID: Date: 17 May 91 21:47:21 GMT References: <519f23cc.19260@apollo.HP.COM> Organization: Rutgers Univ., New Brunswick, N.J. Lines: 97 williams_j@apollo.HP.COM (Jim Williams) writes: >I would like to throw out some ideas for discussion. Hopefully these >concepts have not already been discussed to death. >--------------------------- Example 1 ------------------------------------------ >class A; >class B; >B* f(A* ap) {return (B*)ap;} >-------------------------------------------------------------------------------- >The compiler accepts the above code with no problems. But how can the complier >cast an A pointer to a B pointer? The compiler doesn't know anything (yet) >about A or B. Is A derived from B? Is B derived from A? If B is virtually >derived from A, the cast in f() is illegal, but the compiler, not knowing if >B is virtually derived from A, signals no error. Does this make sense? Let's call things like "class A;" *class declarations* and the actual "class A {...};" the *class definition*. An easy way to solve this problem would be to require a class declaration to list the bases classes of the class defined. So your example might turn into: class Q ; class X ; class Y ; class Z ; class M : public virtual Q, public X, protected Y, Z ; class N : public virtual Q, X ; class A : public N, M ; class B : virtual A ; ... which is long, but allows the compiler to figure out how to generate the cast correctly. >--------------------------- Example 2 ------------------------------------------ >class A { > int take_up_space; > }; >class C; // this declaration is required so B::next() can be defined >class B { > B* next_b; // this is a pointer to another B; > public: > C* next() {return ( (C*)next_b ); } // this function accesses next_b, > }; // and casts it. >class C: public A, public B {}; So, in my scheme, an error would be signaled here telling you that you declared C to have no base classes and now are defining it with some base classes. The advantage of this idea is that no run-time errors need ever be generated since the compiler will always have enough information to do it's job correctly. The main disadvantages I can see are (1) you could get long strings of class declarations (as in my rewritten example one); and (2) some existing code will generate errors. To help avoid code breaking, we could say that the error would only be issued in case of multiple inheritence or virtual base classes, so that most current code will be okay (and a good chunk of that that will break won't work correctly now anyway). The error message could be phased in: for now, a warning would be generated, and only in later versions would the user get the actual error. So the proposal would be (with the terminology above): Declarations of classes are allowed to list the base classes of the declared class. (I'm not sure that this is allowed now, although g++ accepted an example). A declaration of a class must match the definition of that class (that is, it must list the same base classes with the same specifiers for each base class) except that a declaration without any base classes may have one non-virtual base class (although a warning may be issued and this feature may be deleted in the future). If the declaration does not match the definition, the behaviour of casts involving the class in question (and pointers to that class, and so on) is undefined for all casts that are in the scope of the incorrect declaration but not the definition, and warning(s) may be issued. (In future, an error may be generated). Note that if the definition and the incorrect declaration are in different files, it may not be possible for the compiler to detect the problem at all. Any other problems? Should it require that the list of base classes be in the same order as well? Comments welcome! ^.-.^ Mark Purtill purtill@dimacs.rutgers.edu (908)932-4580 (O) ((")) DIMACS, P.O. Box 1179, Rutgers U., Piscataway, NJ 08855 (908)220-6905 (H) ********** Note new area code! We are now (908) rather than (201)! **********