Path: utzoo!attcan!uunet!wuarchive!cs.utexas.edu!ut-emx!nowhere!sking From: sking@nowhere.uucp (Steven King) Newsgroups: comp.lang.c++ Subject: Re: Multiple inheritance with virtual bases Message-ID: <1990Oct29.054455.1989@nowhere.uucp> Date: 29 Oct 90 05:44:55 GMT Organization: nowhere Lines: 95 Unfortunately, my newsfeed is about 4 days behind the rest of the world, and after getting somewhat caught up on my reading of this group, I thought I had stuck my foot in it... However, after further thought, I still believe that my interpretation of what Cfront is doing and why it is doing what it is doing is correct =-} In article <12342@cadillac.CAD.MCC.COM> vaughan@mcc.com (Paul Vaughan) writes: >The discussion between Kazuyuki Hagiwara and Steven King about the >sizes of muliply and virtually derived objects is curious indeed. >Here is what GNU C++ does, followed by cfront 2.0 (Sun C++). [ code already repeated several times not shown ] >bash$ g++ -o trash trash.cc >bash$ trash >A 1000 B 1008 C 1008 D 1028 <= reasonable >bash$ CC -o trash trash.cc >CC trash.cc: >cc -o /d2/prism/prism/src/sim/src/trash -I/net/sunspot/usr/cadsw/CC/sun4/incl trash.c -L/net/sunspot/usr/cadsw/CC/sun4/ -lC >bash$ trash >A 1000 B 1008 C 1008 D 2032 <= unreasonable Curious indeed! The result from g++ is what I thought a better engineered Cfront might do, however, I now think that g++ is wrong. ( see below ) In article rae@gpu.utcs.toronto.edu (Reid Ellis) writes: >The source being discussed is appended at the end of this article >after a linefeed. I noticed that the struct 'D' does not need to use >"virtual" for deriving from B and C [although it shouldn't matter for >this code] and tried removing them. > >Under Apple's MPW C++ compiler, I get the previously mentioned cfront >output: >A 1000 B 1008 C 1008 D 2032 > >If, however, I change the line >"struct D : virtual public B, virtual public C {" >to >"struct D : public B, public C {" >then I get the more expected result of: >A 1000 B 1008 C 1008 D 1020 > >Hope this pins the problem down a bit more. And if you need to, use >this as a workaround. > Reid This, I believe is paramount to the question at hand. The declarations of B and C as virtual to D do affect how subsequent derivations are treated. In article <7050032@hpcupt1.cup.hp.com> jamiller@hpcupt1.cup.hp.com (Jim Miller) writes: > >IMHO: the 2K size is a bug. > > >E&S's ARM, 10.1: " > > class V { /* ... */ }; > class A : virtual public V { /* ... */ }; > class B : virtual public V { /* ... */ }; > class C : public A, public B { /* ... */ }; > > Here class C has only one sub-object of class V. " yes, but thats a different matter.... Now to the nexus of the question. Given the aforementioned definitions of A, B, C, and D, we derive class E : public virtual B { int evar; } ; class F : public D, public E { int fvar ; } ; now F::E and F::D not only share a common A, but a common B as well. However, methods that act upon E do not know anything D or D's defintion of B. If, the definition of D is such that B and C are collapsed together as it appears that g++ is doing, then E's methods, with compiler generated offsets into B, are, in fact, going to munge C or D. Only Cfront's inclusion of a complete B into D is going to prevent this. This might not be appearent given the above examples, as they are simple enought that the translator/complier could guarantee proper ordering of members, but with arbitrarily complex definitions I dont believe this would always be true. Of course, I could be wrong and this could be a bug in the implementation of Cfront. If so, then I'm sure there is someone out there in netland willing to correct me. =-} -- sking@nowhere | C++ is to C, what espresso is to ..!cs.utexas.edu!ut-emx!nowhere!sking | coffee; Definitely an acquired taste, | but once you have acquired that taste, | you cant go back ...