title: Multiple shared_ptr storing same pointer
body: <p>Consider this program:</p>
  
  <pre><code>#include &lt;memory&gt;
  #include &lt;iostream&gt;
  
  class X
    : public std::enable_shared_from_this&lt;X&gt;
  {
  public:
    struct Cleanup1 { void operator()(X*) const; };
    struct Cleanup2 { void operator()(X*) const; };
    std::shared_ptr&lt;X&gt; lock1();
    std::shared_ptr&lt;X&gt; lock2();
  };
  
  std::shared_ptr&lt;X&gt; X::lock1()
  {
    std::cout &lt;&lt; "Resource 1 locked" &lt;&lt; std::endl;
    return std::shared_ptr&lt;X&gt;(this, Cleanup1());
  }
  
  std::shared_ptr&lt;X&gt; X::lock2()
  {
    std::cout &lt;&lt; "Resource 2 locked" &lt;&lt; std::endl;
    return std::shared_ptr&lt;X&gt;(this, Cleanup2());
  }
  
  void X::Cleanup1::operator()(X*) const
  {
    std::cout &lt;&lt; "Resource 1 unlocked" &lt;&lt; std::endl;
  }
  
  void X::Cleanup2::operator()(X*) const
  {
    std::cout &lt;&lt; "Resource 2 unlocked" &lt;&lt; std::endl;
  }
  
  int main()
  {
    std::cout &lt;&lt; std::boolalpha;
  
    X x;
    std::shared_ptr&lt;X&gt; p1 = x.lock1();
    {
      std::shared_ptr&lt;X&gt; p2 = x.lock2();
    }
  }
  </code></pre>
  
  <p>I don't see anything in the C++11 Standard section 20.7.2 suggesting any of this is invalid.  It's a bit unusual to have two <code>shared_ptr</code> objects store the same pointer <code>&amp;x</code> but not share ownership, and to use "deleters" that do not end the lifetime of <code>*get()</code>, but nothing forbids it.  (And if either of those are entirely unintended, it would be difficult to explain why some <code>shared_ptr</code> member functions accept a <code>std::nullptr_t</code> value.)  And as expected, the program outputs:</p>
  
  <pre><code>Resource 1 locked
  Resource 2 locked
  Resource 2 unlocked
  Resource 1 unlocked
  </code></pre>
  
  <p>But now if I add a bit to <code>main()</code>:</p>
  
  <pre><code>int main()
  {
    std::cout &lt;&lt; std::boolalpha;
  
    X x;
    std::shared_ptr&lt;X&gt; p1 = x.lock1();
    bool test1( x.shared_from_this() );
    std::cout &lt;&lt; "x.shared_from_this() not empty: " &lt;&lt; test1 &lt;&lt; std::endl;
    {
      std::shared_ptr&lt;X&gt; p2 = x.lock2();
    }
    try {
      bool test2( x.shared_from_this() );
      std::cout &lt;&lt; "x.shared_from_this() not empty: " &lt;&lt; test2 &lt;&lt; std::endl;
    } catch (std::exception&amp; e) {
      std::cout &lt;&lt; "caught: " &lt;&lt; e.what() &lt;&lt; std::endl;
    }
  }
  </code></pre>
  
  <p>then things get trickier.  With g++ 4.6.3, I get the output:</p>
  
  <pre><code>Resource 1 locked
  x.shared_from_this() not empty: true
  Resource 2 locked
  Resource 2 unlocked
  caught: std::bad_weak_ptr
  Resource 1 unlocked
  </code></pre>
  
  <p>Why would the second call to <code>shared_from_this()</code> fail?  All the requirements of 20.7.2.4p7 are met:</p>
  
  <blockquote>
    <p><em>Requires:</em> <code>enable_shared_from_this&lt;T&gt;</code> shall be an accessible base class of <code>T</code>. <code>*this</code> shall be a subobject of an object <code>t</code> of type <code>T</code>.  There shall be at least one <code>shared_ptr</code> instance <code>p</code> that <em>owns</em> <code>&amp;t</code>.</p>
  </blockquote>
  
  <p>[<code>T</code> is <code>X</code>, <code>t</code> is <code>x</code>, <code>p</code> is <code>p1</code>.]</p>
  
  <p>But g++'s <code>enable_shared_from_this</code> essentially follows the suggested implementation from the (non-normative) "Note" in 20.7.2.4p10, using a private <code>weak_ptr</code> member in class <code>enable_shared_from_this</code>.  And it seems impossible to account for this sort of issue without doing something considerably more complicated in <code>enable_shared_from_this</code>.</p>
  
  <p>Is this a defect in the Standard?  (If so, no comment is needed here on what the solution "should" be: add a requirement so the example program invokes Undefined Behavior, change the Note to not suggest such a simple implementation would be sufficient,....)</p>