rtti data structures (again)
Nathan Sidwell
sidwell at codesourcery.com
Wed Jan 26 14:21:35 UTC 2000
Hi,
Sorry, there are still some problems with the rtti data layout, which
I'd not noticed (cos I implemented what I thought was written, not
what's actually written).
1) The amended (25th Jan) RTTI says
'Note that the full structure described by an RTTI descriptor may
include incomplete types not required by the Standard to be
completed, although not in contexts where it would cause ambiguity.'
I don't believe this is the case, the example I posted a couple of weeks
back pointed this out. Here it is, in a slightly more compact form
struct A;
struct B;
int main ()
{
try {
throw (B **)0;
} catch (A const * const *) {
abort ();
} catch (B const * const *) {
;//ok
} catch (...) {
abort ();
}
}
I believe this is well formed and should not abort. The RTTI document
indicates that `typeid (A const * const *)' and
`typeid (B const * const *)' will produce __pointer_type_info chains that
end at a weak symbol reference for A and B respectively. These will both
resolve to zero. How is catch matching able to determine the difference
between `A const * const *' and `B const * const *' under these
circumstances? If this is a shortcoming of the ABI, or considered a defect
in the standard, it should be documented.
There seems to be no discussion of this case.
2) __si_class_type_info is documented for a single non-virtual heirarcy,
and __vmi_class_type_info for a class containing (directly or indirectly)
a multiple or virtual inheritance component. My mistake was to use
__si_class_type_info for a class with a single base, regardless of the
heirachy within the base (that is the current g++ behaviour). I can see
that for dynamic_cast, knowing that __si_class_type_info has only single
inheritance could speed up checking for the original source base started
from, in certain circumstances. Primarily these are target to source
checks. However, those cases where the singly inherited nature
of __si_class_type_info helps, are exactly those cases where the
src2dst_offset hint tells us anyway. That hint is more general as it works
in multiple heirarchies too. Hence, we have not gained in restricting
__si_class_type_info to entirely singly inherited classes. We have lost
for cases where a class has a single base which happens to contain
multiple or virtual inheritance. That has to go through the complexity
of the general case.
An additional surprise is in the following,
struct A {int non_empty;};
struct B : A {virtual ~B ();};
struct C : B {};
These are singly inherited graphs. C will be layed out in an
__si_class_type_info. However, B cannot be, because it has introduced
a vtable, which will be at offset zero. So the A base of B will be at
some non-zero offset, which is not representable by __si_class_type_info.
So within an __si_class_type_info heirarchy, there can exist
__vmi_class_type_info nodes.
If it is intended that __si_class_type_info is for completely single
inheritance, could the rationale be documented?
3) __si_class_type_info is for both public and non-public inheritance
(again, something I'd not noticed, thinking it was for public only). For
this to work, the __class_type_info flag bit 0x8 'non-publicly inherited
base' must mean `non-publicly inherited direct base'. Please can the wording
about bases here explicitly say `direct base' `indirect base' or `direct or
indirect base'. The description currently use `contains' and `has' which
are open to interpretation.
In dynamic casting, access is important. In a cross cast from base A via
complete type C to another base B, both B and A must be publicly accessible
from C. It might be that dynamic_cast locates B, and, knowing that C does
not have multiply inherited subobjects, determines it need look no further.
However, it must determine access. If C has no non-public direct or indirect
bases, access must be OK, without further inspection. However the hint flag
0x8 can't be indicating that, as it is only for direct bases. (This was the
one case where I was able to take advantage of these flags, but alas it seems
I can't.)
nathan
--
Dr Nathan Sidwell :: Computer Science Department :: Bristol University
Never hand someone a gun unless you are sure where they will point it
nathan at acm.org http://www.cs.bris.ac.uk/~nathan/ nathan at cs.bris.ac.uk
More information about the cxx-abi-dev
mailing list