title: how to check whether two pointers point to the same object or not?
body: <p>Consider two pointers</p>
  
  <pre><code>A* a; 
  B* b;
  </code></pre>
  
  <p>Both A and B are polymorphic classes.
  How to check whether a and b point to the same object or not?</p>
  
  <p>More precisely, let's specify a and b point to the same object if there exists some object d of type D such that both *a and *b are somewhere in the class hierarchy of d.</p>
  
  <p>I would propose the following solution:</p>
  
  <pre><code>dynamic_cast&lt;void*&gt;(a) == dynamic_cast&lt;void*&gt;(b)
  </code></pre>
  
  <p>Indeed, according to the standard, </p>
  
  <pre><code>dynamic_cast&lt;void*&gt;(v) 
  </code></pre>
  
  <p>yields ”a pointer to the most derived object pointed to by v. (n3242.pdf: § 5.2.7 - 7).
  If the most derived for both is the same object, then the pointers point to the same object.</p>
  
  <p>I'm pretty sure that it should always work correctly from the practical viewpoint. But theoretically, at first glance the proposed equality seems to produce false positive, for example, in case if b points to the first member of A (not to A's ancestor). Although it's practically impossible to get equal addresses for A and its member since  A's virtual table pointer should be located before this member, the standard doesn't mandate virtual tables and says nothing about the class layout. </p>
  
  <p>So, my questions are:</p>
  
  <ol>
  <li><p>Is the proposed solution correct from the standard viewpoint?</p></li>
  <li><p>Are there any caveats about private (protected) inheritance or cv-qualification ?</p></li>
  <li><p>Are there better solutions?</p></li>
  </ol>
  
  <p><b>[EDIT] </b></p>
  
  <p>I tried to present some example that illustrates a relatively complex scenario. In this case dynamic crosscasting and static casting are ambiguous.</p>
  
  <pre><code> // proposed impplementation:
  template&lt;typename P, typename Q&gt; 
  bool test_ptrs(const P* p, const Q* q)
  {
    return (dynamic_cast&lt;const void*&gt;(p) ==  dynamic_cast&lt;const void*&gt;(q));
  }
  
  
  struct Root
  {
    virtual ~Root(){};
  };
  
  struct A: public Root // nonvirtually
  {
  };
  
  struct B: public Root // nonvirtually
  {
  };
  
  struct C: public A, B  // nonvirtual diamond started with Root
  {
    Root another_root_instance;
  };
  
  int main()
  {
    C c;
  
    A* pa= &amp;c;
    B* pb= &amp;c;
  
    bool b = (dynamic_cast&lt;void*&gt;(pa) ==  dynamic_cast&lt;void*&gt;(pb));
  
    Root* pra= dynamic_cast&lt;Root*&gt; (pa); 
    Root* prb= dynamic_cast&lt;Root*&gt; (pb);
  
    //Root* prc= dynamic_cast&lt;Root*&gt; (&amp;c); // runtime error, ambiguous cast
    Root* prr= dynamic_cast&lt;Root*&gt;(pra);
  
    Root* pcar= dynamic_cast&lt;Root*&gt;(pra);
    Root* pcbr= dynamic_cast&lt;Root*&gt;(prb);
  
    if(
        test_ptrs(pa, pb) 
        &amp;&amp; test_ptrs(pra, prb)
        &amp;&amp; !test_ptrs(pa,&amp;c.another_root_instance)
      )
    {
      printf("\n test passed \n");
    }
  }
  </code></pre>