<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 711: Contradiction in empty shared_ptr</title>
<meta property="og:title" content="Issue 711: Contradiction in empty shared_ptr">
<meta property="og:description" content="C++ library issue. Status: C++11">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue711.html">
<meta property="og:type" content="website">
<meta property="og:image" content="http://cplusplus.github.io/LWG/images/cpp_logo.png">
<meta property="og:image:alt" content="C++ logo">
<style>
  p {text-align:justify}
  li {text-align:justify}
  pre code.backtick::before { content: "`" }
  pre code.backtick::after { content: "`" }
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table.issues-index { border: 1px solid; border-collapse: collapse; }
  table.issues-index th { text-align: center; padding: 4px; border: 1px solid; }
  table.issues-index td { padding: 4px; border: 1px solid; }
  table.issues-index td:nth-child(1) { text-align: right; }
  table.issues-index td:nth-child(2) { text-align: left; }
  table.issues-index td:nth-child(3) { text-align: left; }
  table.issues-index td:nth-child(4) { text-align: left; }
  table.issues-index td:nth-child(5) { text-align: center; }
  table.issues-index td:nth-child(6) { text-align: center; }
  table.issues-index td:nth-child(7) { text-align: left; }
  table.issues-index td:nth-child(5) span.no-pr { color: red; }
  @media (prefers-color-scheme: dark) {
     html {
        color: #ddd;
        background-color: black;
     }
     ins {
        background-color: #225522
     }
     del {
        background-color: #662222
     }
     a {
        color: #6af
     }
     a:visited {
        color: #6af
     }
     blockquote.note
     {
        background-color: rgba(255, 255, 255, .10)
     }
  }
</style>
</head>
<body>
<hr>
<p><em>This page is a snapshot from the LWG issues list, see the <a href="lwg-active.html">Library Active Issues List</a> for more information and the meaning of <a href="lwg-active.html#C++11">C++11</a> status.</em></p>
<h3 id="711"><a href="lwg-defects.html#711">711</a>. Contradiction in empty <code>shared_ptr</code></h3>
<p><b>Section:</b> 20.3.2.2.6 <a href="https://wg21.link/util.smartptr.shared.obs">[util.smartptr.shared.obs]</a> <b>Status:</b> <a href="lwg-active.html#C++11">C++11</a>
 <b>Submitter:</b> Peter Dimov <b>Opened:</b> 2007-08-24 <b>Last modified:</b> 2016-01-28</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all other</b> <a href="lwg-index.html#util.smartptr.shared.obs">issues</a> in [util.smartptr.shared.obs].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#C++11">C++11</a> status.</p>
<p><b>Discussion:</b></p>
<p>
A discussion on
<a href="http://groups.google.com/group/comp.std.c++/browse_frm/thread/8e89dceb35cd7971">comp.std.c++</a>
has identified a contradiction in the <code>shared_ptr</code> specification.
The note:
</p>

<blockquote><p>
[ <i>Note:</i> this constructor allows creation of an empty shared_ptr instance with a non-NULL stored pointer.
-end note ]
</p></blockquote>

<p>
after the aliasing constructor
</p>

<blockquote><pre>
template&lt;class Y&gt; shared_ptr(shared_ptr&lt;Y&gt; const&amp; r, T *p);
</pre></blockquote>

<p>
reflects the intent of
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2351.htm">N2351</a>
to, well, allow the creation of an empty <code>shared_ptr</code>
with a non-NULL stored pointer.
</p>

<p>
This is contradicted by the second sentence in the Returns clause of 20.3.2.2.6 <a href="https://wg21.link/util.smartptr.shared.obs">[util.smartptr.shared.obs]</a>:
</p>

<blockquote>
<pre>
T* get() const;
</pre>
<blockquote><p>
<i>Returns:</i> the stored pointer. Returns a null pointer if <code>*this</code> is empty.
</p></blockquote>
</blockquote>

<p><i>[
Bellevue:
]</i></p>


<blockquote>
<p>
Adopt option 1 and move to review, not ready.
</p>
<p>
There was a lot of confusion about what an empty <code>shared_ptr</code> is (the term
isn't defined anywhere), and whether we have a good mental model for how
one behaves. We think it might be possible to deduce what the definition
should be, but the words just aren't there. We need to open an issue on
the use of this undefined term. (The resolution of that issue might
affect the resolution of issue <a href="lwg-defects.html#711" title="Contradiction in empty shared_ptr (Status: C++11)">711</a><sup><a href="https://cplusplus.github.io/LWG/issue711" title="Latest snapshot">(i)</a></sup>.)
</p>
<p>
The LWG is getting more uncomfortable with the aliasing proposal (N2351)
now that we realize some of its implications, and we need to keep an eye
on it, but there isn't support for removing this feature at this time.
</p>
</blockquote>

<p><i>[
Sophia Antipolis:
]</i></p>


<blockquote>
<p>
We heard from Peter Dimov, who explained his reason for preferring solution 1.
</p>
<p>
Because it doesn't seem to add anything. It simply makes the behavior
for p = 0 undefined. For programmers who don't create empty pointers
with p = 0, there is no difference. Those who do insist on creating them
presumably have a good reason, and it costs nothing for us to define the
behavior in this case.
</p>
<p>
The aliasing constructor is sharp enough as it is, so "protecting" users
doesn't make much sense in this particular case.
</p>
<p>
> Do you have a use case for r being empty and r being non-null? 
</p>
<p>
I have received a few requests for it from "performance-conscious"
people (you should be familiar with this mindset) who don't like the
overhead of allocating and maintaining a control block when a null
deleter is used to approximate a raw pointer. It is obviously an "at
your own risk", low-level feature; essentially a raw pointer behind a
shared_ptr facade.
</p>
<p>
We could not agree upon a resolution to the issue; some of us thought
that Peter's description above is supporting an undesirable behavior.
</p>
</blockquote>

<p><i>[
2009-07 Frankfurt:
]</i></p>


<blockquote>
<p>
We favor option 1, move to Ready.
</p>
<p><i>[
Howard:  Option 2 commented out for clarity, and can be brought back.
]</i></p>

</blockquote>



<p id="res-711"><b>Proposed resolution:</b></p>
<p>
In keeping the N2351 spirit and obviously my preference, change 20.3.2.2.6 <a href="https://wg21.link/util.smartptr.shared.obs">[util.smartptr.shared.obs]</a>:
</p>

<blockquote>
<pre>
T* get() const;
</pre>
<blockquote><p>
<i>Returns:</i> the stored pointer. <del>Returns a null pointer if <code>*this</code> is empty.</del>
</p></blockquote>
</blockquote>








</body>
</html>
