Pointer values are different but they compare equal. Why?

Solution 1:

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.

Solution 2:

The memory layout of an object of type C will look something like this:

|   <---- C ---->   |
|-A: a-|-B: b-|- c -|
0      4      8     12

I added the offset in bytes from the Address of the object (in a platform like yours with sizeof(int) = 4).

In your main, you have two pointers, I'll rename them to pb and pc for clarity. pc points to the start of the whole C object, while pb points to the start of the B subobject:

   |   <---- C ---->   |
   |-A: a-|-B: b-|- c -|
   0      4      8     12
pc-^   pb-^

This is the reason why their values are different. 3E9A98+4 is 3E9A9C, in hex.

If you now compare those two pointers, the compiler will see a comparison between a B* and a C*, which are different types. So it has to apply an implicit conversion, if there is one. pb cannot be converted into a C*, but the other way round is possible - it converts pc into a B*. That conversion will give a pointer that points to the B subobject of wherever pc points to - it is the same implicit conversion used when you defined B* pb = pc;. The result is equal to pb, obviously:

   |   <---- C ---->   |
   |-A: a-|-B: b-|- c -|
   0      4      8     12
pc-^   pb-^
   (B*)pc-^

So when comparing the two pointers, the compiler in fact compares the converted pointers, which are equal.