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

Issue

This Content is from Stack Overflow. Question asked by xmh0511

#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?



Solution

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.


This Question was asked in StackOverflow by xmh0511 and Answered by Ted Lyngmo It is licensed under the terms of CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.

people found this article helpful. What about you?