[cxx-abi-dev] pointer-to-data-member representation for null pointer is not conforming

Dennis Handly dhandly at cup.hp.com
Fri Dec 21 05:14:10 UTC 2012


>From: Richard Smith <richardsmith at google.com>
>struct E {};
>struct X : E {};
>struct C : E, X { char x; };

>char C::*c1 = &C::x;
>char X::*x = (char(X::*))c1;
>char C::*c2 = x2;

Should this just be "x"?

>[expr.static.cast]p12, we can convert a pointer to a member of a derived
>class to a pointer to a member of a base class

Even if that class doesn't have members of that type?

>Per the ABI, C::x is at offset 0, C::E is at offset 0, and C::X and C::X::E
>are at offset 1

Computing the offsets for x, C::X and C::X::E gives those values.
(I'm not sure how to compute the offset of C::E?)

>the conversion from x to c2 preserves the -1 value (conversion of
>a null member pointer produces a null member pointer), giving the wrong
>value for x2, and resulting in main returning 0, where the standard
>requires it to return 1 (likewise, returning x != 0 would produce the wrong
>value).

I assume that x and x2 are really the same, typo?

Trying this with g++ (4.2.1), I get the right answer.
But it has this warning on the C definition:
abi_ptm.c:4: warning: direct base 'E' inaccessible in 'C' due to ambiguity

Most likely since you can't do this cast:  ??
   void *pE = (E*)&c;

aC++ (EDG based) gets the wrong answer.
So is g++ using advanced AI technology to get the right answer?

Looking at the assembly, there doesn't seem to be any code to handle NULL
being cast back to a derived class.


More information about the cxx-abi-dev mailing list