Topic: tagged unions, an alternative to RTTI (run-time type checking)


Author: tmb@arolla.idiap.ch (Thomas M. Breuel)
Date: 29 Jul 92 16:53:22 GMT
Raw View
In article <1992Jul28.183746.24287@ucc.su.OZ.AU> maxtal@extro.ucc.su.OZ.AU (John MAX Skaller) writes:

   >Consider the classic "List" class and "ListNode" class.
   >ListNode is a base class, and assume there are two flavors
   >of derived node.  We write a List that contains a mix of
   >these nodes out to a file; now we want to read the List back
   >in and reconstruct it.
   >
   >Can it be done without resorting to an isA() member function,
   >some member data to identify node type, and possibly some
   >casting/conversion?

    a) without some type information, it cant be done.
    b) without casting it can (and should :-) be done

    union hetero {
     type1 *p1;
     type2 *p2;
    };


   And the list is homogeneous--all the elements are of type 'hetero'.

It would, in fact, be nice if C++ had a tagged union type, like Pascal
or SML. Something along the lines of:

union hetero int {
case 1: type1 *p1;
case 2: type2 *p2;
};

int f(hetero h) {
 switch(h) {
 case 1: return h.p1->foo();
 case 2: return h.p2->bar();
 }
}

void g(hetero &h) {
 // set the tag of "h" to "1" and the value of p1 to NULL
 h.p1 = 0;
}

The members of tagged unions should usually only be used inside a
switch statement (note that switching on a tagged union is a new
construct, distinct from switching on an integral type).  Updates of
one of the members would automatically update the type tag.  There are
probably some additional syntactic and semantic issues to be resolved.

I think such a facility would be very useful and have some advantages
over RTTI:

 * works for any collection of types (objects don't have to have
   virtual function tables, etc.)

 * the compiler can warn about type cases that the programmer
   has forgotten to handle in his "switch" statement

 * tagged unions would allow objects with constructors/destructors
   in unions

 * easy to implement and explain

     Thomas.