Pointers-to-members
Jim Dehnert
dehnert at baalbek.engr.sgi.com
Tue Feb 29 21:45:31 UTC 2000
> From: Christophe de Dinechin <ddd at cup.hp.com>
>
> Mark Mitchell wrote:
> >
> > I think I submitted a "proof" of the non-negativity of
> > pointers-to-members in all cases. I believe that you can't cast a
> > D::* to a B::* if B is a virtual base.
>
> I believe in the proof. Yet, I'm a bit nervous, because the aCC compiler
> currently had large delta between actual pointer to members and NULL pointer to
> members. Just paranoia? Maybe. Or maybe there is a case we don't think of...
> That's why I proposed 0x800...000 as the NULL value.
OK, I got ambitious (foolish? reckless?) and went searching through the
Standard for pointers to members. Here's what I found:
- There is a standard conversion (4.11) from A::* to B::* (same type)
if B is derived from A, and A is not an inaccessible, ambiguous, or
virtual base of B.
- There is a static cast (5.2.9) from B::* to A::* if the opposite
standard conversion exists. Note that this still excludes crossing
the virtual base boundary. The pointee member need not be in the
target class, but must be in one of the classes derived from it.
- There is a reinterpret cast (5.2.10), but the only requirements are
that NULL becomes NULL, and it is invertible.
- Comparisons (5.10) of pointers to virtual member functions are undefined.
So, conclusions:
- Since we always allocate non-virtual bases before data members,
any base object in a derivation chain will have its base address
smaller than any of the data members declared in members of the
chain. Therefore, the offset represented by a pointer-to-data-member
will always be non-negative, even after the permitted conversions
above.
So, we could either use -1 for NULL, or use 0 and increment the
offset. 0x800...000 is an unnecessary complication.
- For pointer-to-function-member comparisons, we only need to worry
about non-virtual members and null. Since the representation
stores the actual address of the function descriptor, we should be
able to just compare the pointers, and ignore the adjustment.
For conversions between base classes, it seems that we need only
modify the adjustment, and then only if one is not primary for the
other. For conversion to null, it seems that we need only set the
pointer to 0, and can ignore the adjustment.
This seems simple enough. So I must be missing something :-).
Jim
- Jim Dehnert dehnert at sgi.com
(650)933-4272
More information about the cxx-abi-dev
mailing list