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

Richard Smith richardsmith at google.com
Fri Dec 21 00:19:27 UTC 2012


Hi,

Consider the following:

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;

int main() { return c2 != 0; }

I believe this program is valid and has defined behavior; per
[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, so long as the base class
is a base class of the class containing the original member.

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 (they can't go at 0 due to the collision of the empty E
base class). So the value of c1 is 0. And the value of x is... -1. Whoops.

Finally, 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).
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://sourcerytools.com/pipermail/cxx-abi-dev/attachments/20121220/f6e356ee/attachment.html>


More information about the cxx-abi-dev mailing list