TITLE: multiple addresses for a single instance (Newsgroups: comp.lang.c++.moderated, 5 Jun 97) [ This is part of a discussion over the idiom used in protecting operator= from self assignment as shown below: T& T::operator=( const T& other ){ if( this != &other ) { // the test in question // ... } } - adc ] POTTER: John Potter | : Consider a classic diamond-shaped inheritance lattice with non- | : virtual inheritance: | : A | : / \ | : / \ | : B C | : \ / | : \ / | : D | : D can have up to five distinct addresses, depending on its context | : [Meyers: "Effective C++" p. 57]. EVERS: Wil Evers | The context is D& D::operator= (D const&). As a D*, there is only one | address for a D object. The addresses for the B part, the A part of | the B part, the C part, the A part of the C part could all be | different and the address of D could be assigned to a pointer of type | A*, B*, C* and would then not be equal to the address of D as a D*. | | I too was stunned by that passage in Scott's book - however, I think it is | misleading. | | While it is true that an implementation may use different physical | addresses for each of the different (sub-)objects in the above hierarchy, | it is definitely not allowed to come up with two pointers that don't | compare equal if the address of some derived object is converted to the | same base class pointer type twice, even in the face of multiple | inheritance. MEYERS: smeyers@teleport.com (Scott Meyers) My book is wrong here ("misleading" is too kind, Wil, but thanks :-}), and John and Wil are completely right. True, an object of type D may have many different physical addresses, but each of those addresses has a type, and compilers will see to it that the addresses are adjusted correctly (based on their common type) any time you compare them. The only time this isn't true is when you cast to void*, i.e., something like this: D d; B *pB = &d; // make pB point to d C *pC = &d; // make pC point to d if (pB == pC) ... // assuming B and C virtually inherit from A, // this will return true, because both pB and pC // will be converted to A* before they are compared, // if A is not a virtual base class, both pointers // will still be converted to A* pointers prior to // the comparison, but the test will (properly) // return false if ((void*)pB == (void*)pC) ... // this will almost certainly return // false, because the B and C parts of // d are at different physical locations I made the mistake in the book because (1) I overlooked the fact that the pointer types would be converted to a common type prior to the comparison and (2) the context of the discussion was operator=, where the prototypical test of "this" agains "&rhs" is comparing pointers of the same type. I'm sorry for the misinformation the book contains. What can I say? I was young. It was dark. There were so many rules...