🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.std.c++
Article #989

Objects already contain type information => binary virtual functions

#989
From: Tom Ngo
Date: Thu, 28 Mar 1991 14:36
75 lines
3011 bytes
Here's a wild idea whose purpose is to permit typesafe downcasts under
certain circumstances.  Do others think it's worth pursuing?  Can it
be generalized?

The problem:

    class B {
        virtual void foo(B*);
    };
    class D : public B {
        virtual void foo(D*);
    };

    void bar(B* b1, B* b2) {
        b1.foo(b2);
    }

    D d1;
    D d2;
    bar(&d1,&d2);            // I want D::foo to be invoked

    Currently, D::foo does not override B::foo.  A way to cause this
    to happen is for D::foo to be declared D::foo(B*) and downcast B*
    to D* within the body of D::foo.   This downcast is considered
    unsafe; see ARM p. 210-211.

    I call foo() a "binary" virtual function, meaning that the
    intention is for it to operate on two objects of identical type,
    even if the call is made with references or pointers to a base
    class of the type.

    I feel there is a strong need for such functions, and that
    currently there is no way to implement them that is both typesafe
    and elegant.  For example, if you have a container class designed
    to take B*'s and you have given it all D*'s, the container class
    ought to be able to do things like compare objects in a D-specific
    manner, etc.  Right now if you want to implement this sort of
    thing in a typesafe manner you have to make two separate virtual
    function calls, one for each operand of the comparison, or some
    such thing.

The proposed solution:

    It has been argued that to implement typesafe downcasts would
    require that type information be added to each object.  I suggest
    that objects already contain type information in their virtual
    function tables.  So here's the idea:

    1.  Relax the requirement that two functions' arguments match
        EXACTLY for one to override the other.  Instead, permit
        D::foo(D*) to match B::foo(B*).

        (In general, any argument of type D* or D* in the argument
        list of D::foo would match an argument of type B* or B* in
        B::foo.) 

    2.  In that case, in D::foo(D* that) the compiler should
        automatically generate code that ensures:

            this->foo == that->foo

        (You know what I mean.)  If the equality fails, then perhaps
        an addressing exception should be generated.

    This solution generalizes trivially to cases in which D::foo has
    several D* arguments.

Comments?

--Tom
--
  Tom Ngo
  ngo@harvard.harvard.edu
  617/495-1768 lab number, leave message
Technical Details
Message-ID: <NGO.91Mar28093648@tammy.harvard.edu>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!rpi!usc!snorkelwacker.mit.edu!hsdndev!husc6!ngo

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!rpi!usc!snorkelwacker.mit.edu!hsdndev!husc6!ngo
From: ngo@tammy.harvard.edu (Tom Ngo)
Newsgroups: comp.std.c++
Subject: Objects already contain type information => binary virtual functions
Message-ID: <NGO.91Mar28093648@tammy.harvard.edu>
Date: 28 Mar 91 14:36:48 GMT
Sender: news@husc6.harvard.edu
Distribution: comp
Organization: Harvard Chemistry Department
Lines: 75