[comp.std.c++] Casting within MI Graphs

sdm@cs.brown.edu (Scott Meyers) (08/25/90)

Does E&S prohibit explicit casts from pointers to virtual base classes to
pointers to derived classes?  The only thing I can find is in the
commentary on page 227:

    Casting from a virtual base class to a derived class is disallowed to
    avoid requiring an implementation to maintain pointers to enclosing
    objects. 

However, this passage is commentary, not proposed law.  Is there such a
restruction proposed for standard C++?

A similar question arises from the commentary on page 222:

    Casting a value to a pointer to a base class and then to some other
    type may not yield the same result as casting directly to the second
    type. 

Again, is this merely commentary, or is it part of the proposed language
standard?  In general, I don't have a problem with it, but when casting up
and down an inheritance hierarchy, I would like casts to always "do the
right thing."  That is, given:

        A      
       / \     
      /   \     A is the top of the hierarchy and may be a virtual base
     B     C    class for B and C.
      \   /
       \ /
        D

    A *p = new D;
    void *pv;

I want the following to all yield equivalent results:

    pv = p;
    p = (D *) pv;

    pv = (B *) p;
    p = (D *) (A *) pv;

    pv = (A *) p;
    p = (D *) (B *) pv;

    etc.

Ditto for these:

    pv = p;
    p = (B *) pv;
    p = (B *) (D *) pv;

    etc.

These considerations are important in the common case where A, B, and C are
all abstract classes, so collections of A, B, and C pointers are really all
collections of pointers to D objects.  If casting order makes a difference,
then it's not enough to know that everything in a list of A pointers is
really a D pointer, because you have to know the order in which pointer
casts were applied if you want to reliably convert the underlying D
pointers to A, B, C, or D pointers.  Similarly, if casts from virtual bases
to derived objects are disallowed, then collections of pointers to A
objects are next to useless.

To summarize:

    - Casts from pointer-to-virtual-base to pointer-to-derived should be
      allowed.

    - The order of application of casts between object pointer types within
      an inheritance graph should not matter in terms of the final result.
      (Obviously, user-defined casting functions are excluded.)

Scott

cline@cheetah.ece.clarkson.edu (Marshall Cline) (08/27/90)

In article <48168@brunix.UUCP> sdm@cs.brown.edu (Scott Meyers) writes:
> Does E&S prohibit explicit casts from pointers to virtual base classes to
> pointers to derived classes?

Yes, these casts, even though explicit, are illegal.  The July issue of
The C++ Report contains a C++ Puzzle solution showing why.  Basically
there is no way of knowing at compile time how to perform the cast.  The
cover article in the same issue shows a portable method of faking the
cast.  The method requires maintaining run-time type information.

Marshall Cline
--
==============================================================================
Marshall Cline / Asst.Prof / ECE Dept / Clarkson Univ / Potsdam, NY 13676
cline@sun.soe.clarkson.edu / Bitnet:BH0W@CLUTX / uunet!clutx.clarkson.edu!bh0w
Voice: 315-268-3868 / Secretary: 315-268-6511 / FAX: 315-268-7600
Career search in progress; ECE faculty; research oriented; will send vita.
PS: If your company is interested in on-site C++/OOD training, drop me a line!
==============================================================================

sdm@cs.brown.edu (Scott Meyers) (08/28/90)

In article <CLINE.90Aug27124642@cheetah.ece.clarkson.edu> cline@sun.soe.clarkson.edu (Marshall Cline) writes:
| In article <48168@brunix.UUCP> sdm@cs.brown.edu (Scott Meyers) writes:
| > Does E&S prohibit explicit casts from pointers to virtual base classes to
| > pointers to derived classes?
| 
| Yes, these casts, even though explicit, are illegal.  The July issue of
| The C++ Report contains a C++ Puzzle solution showing why.  Basically
| there is no way of knowing at compile time how to perform the cast.  The
| cover article in the same issue shows a portable method of faking the
| cast.  The method requires maintaining run-time type information.

Do you have a reference for where in E&S they are declared illegal?  As I
said, I found such a prohibition only in the commentary.

Unfortunately, I don't have access to the C++ Report, but the commentary of
E&S outlines an implementation for virtual base classes that makes it
impossible to do downward casts such as I described, and I suspect this is
the implementation discussed in the C++ Report.  As the discussion in E&S
implies, there are alternative implementations for virtual bases that allow
for well-defined downward casts, but they require more memory per object.

Scott

thomasw@hpcupt1.HP.COM (Thomas Wang) (08/28/90)

/ hpcupt1:comp.std.c++ / sdm@cs.brown.edu (Scott Meyers) / 12:23 pm  Aug 27, 1990 /
In article <CLINE.90Aug27124642@cheetah.ece.clarkson.edu> cline@sun.soe.clarkson.edu (Marshall Cline) writes:

>Unfortunately, I don't have access to the C++ Report, but the commentary of
>E&S outlines an implementation for virtual base classes that makes it
>impossible to do downward casts such as I described, and I suspect this is
>the implementation discussed in the C++ Report.  As the discussion in E&S
>implies, there are alternative implementations for virtual bases that allow
>for well-defined downward casts, but they require more memory per object.

The current C++ implementation of MI have yet another defect.  The location
of data members inside a virtual object is undefined until the object is
initialized.  This means that functions such as print_all_data_member(), when
called during initialization phase, would segment fault because it would
likely access address 0.

The function mark_all_data_member(), and sweep_all_data_member() would not
work when called during construction phase.  These two subroutines are used to
implement mark & sweep memory management.  They will be called anytime memory
is nearly exhausted.

> Scott

 -Thomas Wang
              (Everything is an object.)
                                                     wang@hpdmsjlm.cup.hp.com
                                                     thomasw@hpcupt1.cup.hp.com