Title
Criterion for equality of pointers to members
Status
c++14
Section
7.6.10 [expr.eq]
Submitter
Richard Smith

Created on 2012-12-21.00:00:00 last changed 81 months ago

#### Messages

Date: 2014-02-15.00:00:00

[Moved to DR at the February, 2014 meeting.]

Date: 2014-01-15.00:00:00

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]

• Two Otherwise, 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]

Date: 2012-12-21.00:00:00

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.

History
Date User Action Args