Pointer values are different but they compare equal. Why?

xmllmx picture xmllmx · Aug 16, 2013 · Viewed 9.7k times · Source

A short example outputs a weird result!

#include <iostream>

using namespace std;

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

int main()
{
    C* c = new C;
    B* b = c;

    cout << "The address of b is 0x" << hex << b << endl;
    cout << "The address of c is 0x" << hex << c << endl;

    if (b == c)
    {
        cout << "b is equal to c" << endl;
    }
    else
    {
        cout << "b is not equal to c" << endl;
    }
}

It's very surprising to me that the output should be as follows:

The address of b is 0x003E9A9C
The address of c is 0x003E9A98
b is equal to c

What makes me wonder is:

0x003E9A9C is not equal to 0x003E9A98, but the output is "b is equal to c"

Answer

Mike Seymour picture Mike Seymour · Aug 16, 2013

A C object contains two sub-objects, of types A and B. Obviously, these must have different addresses since two separate objects can't have the same address; so at most one of these can have the same address as the C object. That is why printing the pointers gives different values.

Comparing the pointers doesn't simply compare their numeric values. Only pointers of the same type can be compared, so first one must be converted to match the other. In this case, c is converted to B*. This is exactly the same conversion used to initialise b in the first place: it adjusts the pointer value so that it points to the B sub-object rather than the C object, and the two pointers now compare equal.