What is the result of relational operations on two pointers to different base class subobject

Viewed 73
#include <iostream>

struct A{
    int a;
};
struct B{
    float b;
};
struct C:A,B{
    int c;
};

int main(){
  C* ptr = new C{};
  A* aptr = ptr;
  B* bptr = ptr;
  bool b = (void*)bptr > (void*)aptr;
  bool b2 = (void*)aptr > (void*)bptr;
  std::cout<< b<<std::endl;
  std::cout<< b2<<std::endl;
}

In this example, both GCC and Clang say bptr is greater than aptr. However, [expr.rel] p4 says

The result of comparing unequal pointers to objects71 is defined in terms of a partial order consistent with the following rules:

  • If two pointers point to different elements of the same array, or to subobjects thereof, the pointer to the element with the higher subscript is required to compare greater.
  • If two pointers point to different non-static data members of the same object, or to subobjects of such members, recursively, the pointer to the later declared member is required to compare greater provided neither member is a subobject of zero size and their class is not a union.
  • Otherwise, neither pointer is required to compare greater than the other.

Obviously, in this case, the third bullet applies to this case. The result should be false for both b and b2. What's the reason Clang and GCC say bptr is greater than aptr?

1 Answers

Obviously, in this case, the third bullet applies to this case

No, the second bullet applies. a and b are non-static data members of the same object (the C instance).

If two pointers point to different non-static data members of the same object, or to subobjects of such members, recursively, the pointer to the later declared member is required to compare greater provided neither member is a subobject of zero size and their class is not a union.

And struct C : A,B makes B declared later than A so bptr > aptr == true.

Related