[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