<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 575: the specification of ~shared_ptr is MT-unfriendly, makes implementation assumptions</title>
<meta property="og:title" content="Issue 575: the specification of ~shared_ptr is MT-unfriendly, makes implementation assumptions">
<meta property="og:description" content="C++ library issue. Status: CD1">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue575.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#CD1">CD1</a> status.</em></p>
<h3 id="575"><a href="lwg-defects.html#575">575</a>. the specification of ~shared_ptr is MT-unfriendly, makes implementation assumptions</h3>
<p><b>Section:</b> 20.3.2.2.3 <a href="https://wg21.link/util.smartptr.shared.dest">[util.smartptr.shared.dest]</a>, 99 [tr.util.smartptr.shared.dest] <b>Status:</b> <a href="lwg-active.html#CD1">CD1</a>
 <b>Submitter:</b> Peter Dimov <b>Opened:</b> 2006-04-23 <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.dest">issues</a> in [util.smartptr.shared.dest].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#CD1">CD1</a> status.</p>
<p><b>Discussion:</b></p>
<p>
[tr.util.smartptr.shared.dest] says in its second bullet:
</p>

<p>
"If *this shares ownership with another shared_ptr instance (use_count() &gt; 1),
decrements that instance's use count."
</p>

<p>
The problem with this formulation is that it presupposes the existence of an
"use count" variable that can be decremented and that is part of the state of a
shared_ptr instance (because of the "that instance's use count".)
</p>

<p>
This is contrary to the spirit of the rest of the specification that carefully
avoids to require an use count variable. Instead, use_count() is specified to
return a value, a number of instances.
</p>

<p>
In multithreaded code, the usual implicit assumption is that a shared variable
should not be accessed by more than one thread without explicit synchronization,
and by introducing the concept of an "use count" variable, the current wording
implies that two shared_ptr instances that share ownership cannot be destroyed
simultaneously.
</p>

<p>
In addition, if we allow the interpretation that an use count variable is part
of shared_ptr's state, this would lead to other undesirable consequences WRT
multiple threads. For example,
</p>

<blockquote><pre>
p1 = p2;
</pre></blockquote>

<p>
would now visibly modify the state of p2, a "write" operation, requiring a lock.
</p>


<p id="res-575"><b>Proposed resolution:</b></p>
<p>
Change the first two bullets of [lib.util.smartptr.shared.dest]/1 to:
</p>

<blockquote>
<ul>
<li>If <code>*this</code> is <i>empty</i> <ins>or shares ownership with another
<code>shared_ptr</code> instance (<code>use_count() &gt; 1</code>)</ins>, there are no side effects.</li>
<li><del>If <code>*this</code> <i>shares ownership</i> with another <code>shared_ptr</code> instance
(<code>use_count() &gt; 1</code>), decrements that instance's use count.</del></li>
</ul>
</blockquote>

<p>
Add the following paragraph after [lib.util.smartptr.shared.dest]/1:
</p>

<blockquote><p>
[<i>Note:</i> since the destruction of <code>*this</code> decreases the number of instances in
<code>*this</code>'s ownership group by one, all <code>shared_ptr</code> instances that share ownership
with <code>*this</code> will report an <code>use_count()</code> that is one lower than its previous value
after <code>*this</code> is destroyed. <i>--end note</i>]
</p></blockquote>





</body>
</html>
