From -3830086460461366870
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: f78e5,bed6baff9e441d5c
X-Google-Attributes: gidf78e5,public
X-Google-ArrivalTime: 2003-02-21 12:33:20 PST
Path: archiver1.google.com!news1.google.com!newsfeed.stanford.edu!logbridge.uoregon.edu!kibo.news.demon.net!mutlu.news.demon.net!demon!mail2news.demon.co.uk!devnull
From: dlagno@mail.nnov.ru (Denis Lagno)
Newsgroups: comp.std.c++
Subject: Re: proposal: "virtual restrict" inheritance
Date: Fri, 21 Feb 2003 20:33:19 +0000 (UTC)
Organization: http://groups.google.com/
Lines: 158
Approved: fjh@cs.mu.oz.au (Fergus Henderson , moderator of comp.std.c++)
Message-ID: <5a0f3464.0302210337.50b45855@posting.google.com>
References: <5a0f3464.0302020455.25d887a9@posting.google.com> <7f2735a5.0302131128.115b22fc@posting.google.com>
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
X-Trace: mail2news.demon.co.uk 1045859599 29962 10.0.0.1 (21 Feb 2003 20:33:19 GMT)
X-Complaints-To: abuse@demon.net
NNTP-Posting-Date: Fri, 21 Feb 2003 20:33:19 +0000 (UTC)
X-Received: from mulga.cs.mu.oz.au ([128.250.1.22])
	by news.demon.co.uk with esmtp (Exim 4.05)
	id 18mJrC-0007n7-00
	for mail2news@news.news.demon.net; Fri, 21 Feb 2003 20:33:18 +0000
X-Received: from localhost (localhost [[UNIX: localhost]]) by mulga.cs.mu.OZ.AU
	id HAA11078; Sat, 22 Feb 2003 07:33:14 +1100 (EST)
X-Authentication-Warning: mulga.cs.mu.OZ.AU: fjh set sender to devnull@stump.algebra.com using -f
X-Path: comp-std-cpp-robomod!not-for-mail
X-Robomod: STUMP, ichudov@algebra.com (Igor Chudov)
X-Delivered-To: std-c++@ncar.ucar.edu
X-Newsgroups: comp.std.c++
X-NNTP-Posting-Date: 21 Feb 2003 11:37:11 GMT
X-Spam-Status: No, hits=-9.0 required=5.0
	tests=GAPPY_TEXT,NOSPAM_INC,QUOTED_EMAIL_TEXT,REFERENCES,
	      SPAM_PHRASE_01_02
	version=2.41
Xref: archiver1.google.com comp.std.c++:18003

Concerning your example -- earlier in this thread I've posted several
messages.  One of them gives clear formal preliminary definition of
restricted inheritance.  (w.r.t. == with respect to):

:   10.x  Restricted inheritance                 [class.restrict]
:
: 1 A base class specifier that contains the keyword restrict,
:   specifies a restricted direct base class.  We say that a class
:   without base classes is not restricted w.r.t. any class.
:   A class with restricted direct base class R is restricted
:   via R w.r.t. R and all base classes of R.  A class with direct
:   base class B is restricted via B w.r.t. all classes which B
:   is restricted w.r.t.
:   A class X is restricted w.r.t. to class Y if class X is restricted
:   via some class w.r.t class Y.
:
: 2 A program in which some fixed class X is restricted via more
:   than one class w.r.t. some fixed class B, is ill-formed.
:   [Example:
:           class A1 { /* ... /* };
:           class A2 { /* ... /* };
:           class B1: A1 { /* ... /* };
:           class B2: A2 { /* ... /* };
:           class C: A1, A2 { /* ... /* };
:           class D1: B1, C { /* ... /* };
:           class D2: restrict B2, C { /* ... /* };
:           class E1: restrict D1 { /* ... /* };
:           class E2: D2 { /* ... /* };
:           class F: E1, E2 { /* ... /* };
:   Here F is restricted via E1 w.r.t. D1, B1, C, A1 and A2.
:   F also is restricted via E2 w.r.t. B2 and A2.
:   Hence this program is ill-formed.  --end example]

So in your example

>       B
>      / \
>     C   D
>      \ / \
>       X   Y
>        \ /
>         W
> 
> class B { ... };
> class C: public virtual B { ... };
> class D: public virtual restrict B { ... };
> class X: public C, public D { ... };
> class Y: public D { ... };
> class W: public X, public Y { ... };
> 
> Without the "restrict" keyword, we have two instances of D, but
> only one instance of B. What happens with the restrict keyword?

we have:
B is not restricted w.r.t. anything
C is not restricted w.r.t. anything
D is restricted via B w.r.t. B
X is restricted via D w.r.t. B
Y is restricted via D w.r.t. B
W is restricted via X w.r.t. B
and W is restricted via Y w.r.t. B

so W is restricted via more than 1 class w.r.t. fixed class.  Hence
your example is ill-formed.

---

> How?
> Why is this good?

let's take an example more advanced than simple rhomb.

      B
    / | \
   C  D  E
   \ / \ /
    X   Y

this hierarchy appeared in real-world number-crunching
would-be-high-performance library.  The intended interface of that
library is providing "concrete" classes with certain functionality. It
is not supposed that library users will inherit from provided classes
too intensely.  So in order to optimize one can define classes as:

class B
{
    int m, n;
public:
    int virtual crunch() = 0;
    ...
};

class C: public restrict virtual B { ... };
class D: public virtual B { ... };
class E: public restrict virtual B { ... };
class X: public C, public D { ... };
class Y: public D, public E { ... };

Then compiler can lay out these classes as follows:

#define B_FIELDS()  \
    void *vtable; \
    int m, n;

#define C_FIELDS()  \
    B_FIELDS()      \
    C_stuff;

#define D_FIELDS()  \
    void *vtable;   \
    D_stuff;        \
    B_FIELDS()

#define E_FIELDS()  \
    B_FIELDS()      \
    E_stuff;

#define X_FIELDS()  \
    C_FIELDS()      \
    D_FIELDS()

#define Y_FIELDS()  \
    E_FIELDS()      \
    D_FIELDS()

in such a way access to B::n from everywhere except D* is guaranteed
to be at a fixed offset in an enveloping class no matter what class
the most derived object really is.  Moreover, any (dynamic) cast, put
it, X* <-> B* now can be performed effectively statically since offset
(0 in that case) is known at compile time whatever class the most
derived object really is.  The price is that, for example, user now
cannot inherit both X and Y.  Restricted inheritance can be used
dually.  One use -- provide compiler with a way to optimize
inheritance but pay the price of somewhat restricting further
inheritance.  Second use -- in cases when this price is no price at
all but merit -- when we for example want to implement exclusive
inheritance, we can just write:

class spirit_id {};
class angel_t: restrict spirit_id { ... };
class human_t: restrict spirit_id { ... };

And now we provided guarantee that user cannot be angel and human
simultaneously.

> What would the compiler do differently for
> a "virtual restrict" derivation?

it will not allocate entry in vtable (or in object itself) for offset
(or pointer) of base class.  All accesses, all casts to base class
will be resolved statically.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]



