At a first glance, it seems that one could use the inheritance graph
of Type_infos described in the previous section to implement the PTR_CAST
operation on C++ pointers: in order to cast a pointer p to a C++
type T, retrieve the Type_info t1 of T and t2
of p and check if t2 can be cast to t1 with the previous
method. If so, then return the cast pointer ,
else return NULL.
This simple implementation, described also by [Stroustrup,
1991], fails to work in two major situations. The first situation is
when the type A of p is a virtual base class of B
(Figure 5 a). In this case, C++
will be unable to perform the cast
even though p is in fact pointing to a B. The reason is that
there is no compile-time information that the C++ compiler could use to
perform a
in case p points formally to a virtual base of p. Attempting
to perform such a cast will hence be rejected at compile-time.
Figure 5: Cases when C++ pointer casting will fail to work correctly.
a. Virtual base to derived class cast. b. Cast between types
on different inheritance paths.
The second situation is more dangerous: suppose we have a C++ class
A derived from two classes B and C and a
pointer p which points to an A (Figure 5
b). We should be able to cast p to a C, since it actually
points to an A which is a C also. If we however directly
cast the
to
a
, the compiler
will simply interpret p as pointing to a C without doing
any offset calculations for finding the correct position of the C
subobject in the A subobject. The reason of this is that C++ performs
offset calculations when casting pointers only if the types of those
pointers happen to be on the same path in an inheritance graph. In the
previous example however, C and B are on two different inheritance
paths (which both start at A). In this case, the compiler will not
refuse the cast but simply reinterpret the
as pointing to a
,
which is obviously wrong. Worse, there is no warning issued when such a
cast is performed.
To summarize, direct C++ pointer casting can not be reliably used to implement the PTR_CAST operation, since it works correctly only for types which belong to the same inheritance path and which are not related by virtual inheritance.