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 (on a platform like yours, with sizeof (int) = 4).
Basically, you have two pointers, I will rename them to pb and pc for clarity. pc points to the beginning of the entire object C, and pb points to the beginning of the subobject B:
| <---- C ----> | |-A: a-|-B: b-|- c -| 0 4 8 12 pc-^ pb-^
That is why their meanings are different. 3E9A98 + 4 - 3E9A9C, in hex.
If you compare these two pointers, the compiler will see a comparison between B* and a C* , which are different types. Therefore, he must apply the implicit conversion, if any. pb cannot be converted to C* , but the return path is possible - it converts pc to B* . This conversion will give a pointer pointing to the subobject B where pc pointing out - this is the same implicit conversion that is used when defining B* pb = pc; . The result is pb , obviously:
| <---- C ----> | |-A: a-|-B: b-|- c -| 0 4 8 12 pc-^ pb-^ (B*)pc-^
Therefore, when comparing two pointers, the compiler actually compares the converted pointers equal.
Arne Mertz Aug 16 '13 at 12:21 2013-08-16 12:21
source share