This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115e. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-11-11
[Moved to DR at the February, 2014 meeting.]
According to 7.6.10 [expr.eq] paragraph 2, pointers to data members compare equal
if and only if they would refer to the same member of the same most derived object (6.7.2 [intro.object]) or the same subobject if indirection with a hypothetical object of the associated class type were performed.
This specification is overly constrained. For data members, most implementations simply compare the offsets of the members involved, violating the “only if” part of the specification. For example:
struct A {}; struct B : A { int x; }; struct C : A { int x; }; int A::*bx = (int(A::*))&B::x; int A::*cx = (int(A::*))&C::x; bool b1 = bx == cx;
The existing wording requires b1 to have the value false, even though the offsets of the members are the same. It would be better if the result of the comparison were unspecified unless the class containing the original member for the LHS is a base or derived class of the class containing the original member for the RHS.
Proposed resolution (January, 2014):
Change 7.6.10 [expr.eq] paragraph 3 as follows:
...Comparing pointers to members is defined as follows:
...
If either is a pointer to a virtual member function, the result is unspecified.
If one refers to a member of class C1 and the other refers to a member of a different class C2, where neither is a base class of the other, the result is unspecified. [Example:
struct A {}; struct B : A { int x; }; struct C : A { int x; }; int A::*bx = (int(A::*))&B::x; int A::*cx = (int(A::*))&C::x; bool b1 = (bx == cx); // unspecified
—end example]
TwoOtherwise, two pointers to members compare equal if they would refer to the same member of the same most derived object (6.7.2 [intro.object]) or the same subobject if indirection with a hypothetical object of the associated class type were performed, otherwise they compare unequal. [Example:struct B { int f(); }; struct L : B { }; struct R : B { }; struct D : L, R { }; int (B::*pb)() = &B::f; int (L::*pl)() = pb; int (R::*pr)() = pb; int (D::*pdl)() = pl; int (D::*pdr)() = pr; bool x = (pdl == pdr); // false bool y = (pb == pl); // true—end example]