<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 2337: shared_ptr operator*() should not be noexcept</title>
<meta property="og:title" content="Issue 2337: shared_ptr operator*() should not be noexcept">
<meta property="og:description" content="C++ library issue. Status: NAD">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue2337.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#NAD">NAD</a> status.</em></p>
<h3 id="2337"><a href="lwg-closed.html#2337">2337</a>. <code>shared_ptr operator*()</code> should not be <code>noexcept</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#NAD">NAD</a>
 <b>Submitter:</b> Stephan T. Lavavej <b>Opened:</b> 2013-10-05 <b>Last modified:</b> 2017-07-17</p>
<p><b>Priority: </b>2
</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#NAD">NAD</a> status.</p>
<p><b>Discussion:</b></p>
<p>
20.3.1.3.5 <a href="https://wg21.link/unique.ptr.single.observers">[unique.ptr.single.observers]</a>/3: "<code>pointer operator-&gt;() const noexcept;</code> <i>Requires:</i> <code>get() != nullptr</code>."
<p/>
20.3.2.2.6 <a href="https://wg21.link/util.smartptr.shared.obs">[util.smartptr.shared.obs]</a>/2: "<code>T&amp; operator*() const noexcept;</code> <i>Requires:</i> <code>get() != 0</code>."
<p/>
20.3.2.2.6 <a href="https://wg21.link/util.smartptr.shared.obs">[util.smartptr.shared.obs]</a>/5: "<code>T* operator-&gt;() const noexcept;</code> <i>Requires:</i> <code>get() != 0</code>."
<p/>
Narrow-contract functions should not be <code>noexcept</code>.
</p>

<p><i>[2014-02-15 Issaquah]</i></p>

<p>
Issue is contentious, raise to P2.
</p>

<p><i>[2015-02 Cologne]</i></p>

<p>
AM: This ship has sailed. JM: What's the issue? AM: <code>operator-&gt;</code> has narrow contract and should never have had 
<code>noexcept</code>. DK: Not quite. We explicitly called out that for <code>shared_ptr</code> this is fine. You said so in your 
"narrow contract" paper. GR: This would be a fairly major regression in the design of {<code>unique</code>,<code>shared</code>}<code>_ptr</code> 
over raw pointers; raw pointer dereferencing is <code>noexcept</code>. It's not a performance regression but a usability regression. 
AM: Do we expect users to query <code>noexpect</code> on dereference expressions? Room: Yes. VV: We don't just expect it, we have 
seen it. JM: Yes, users may be querying something like <code>noexcept(x-&gt;y)</code> and expect to be checking <code>y</code>, but 
silently end up checking <code>x-&gt;</code>. 
<p/>
Close as NAD, with explanation from GR.
</p>

<strong>Previous resolution [SUPERSEDED]:</strong>
<blockquote class="note">
<p>This wording is relative to N3691.</p>

<ol>
<li><p>In 20.3.1.3 <a href="https://wg21.link/unique.ptr.single">[unique.ptr.single]</a>/1, class template <code>unique_ptr</code> synopsis for single objects, change as indicated:</p>

<blockquote><pre>
pointer operator-&gt;() const <del>noexcept</del>;
</pre></blockquote>
</li>

<li><p>In 20.3.1.3.5 <a href="https://wg21.link/unique.ptr.single.observers">[unique.ptr.single.observers]</a> change as indicated:</p>

<blockquote><pre>
pointer operator-&gt;() const <del>noexcept</del>;
</pre><blockquote>
<p>
-3- <i>Requires:</i> <code>get() != nullptr</code>.
<p/>
-4- <i>Returns:</i> <code>get()</code>.
<p/>
<ins>-?- <i>Throws:</i> Nothing.</ins>
<p/>
-5- <i>Note:</i> use typically requires that <code>T</code> be a complete type.
</p>
</blockquote></blockquote>
</li>

<li><p>In 20.3.2.2 <a href="https://wg21.link/util.smartptr.shared">[util.smartptr.shared]</a>/1, class template <code>shared_ptr</code> synopsis, change as indicated:</p>

<blockquote><pre>
T&amp; operator*() const <del>noexcept</del>;
T* operator-&gt;() const <del>noexcept</del>;
</pre></blockquote>
</li>

<li><p>In 20.3.2.2.6 <a href="https://wg21.link/util.smartptr.shared.obs">[util.smartptr.shared.obs]</a> change as indicated:</p>

<blockquote><pre>
T&amp; operator*() const <del>noexcept</del>;
</pre><blockquote>
<p>
-2- <i>Requires:</i> <code>get() != 0</code>.
<p/>
-3- <i>Returns:</i> <code>*get()</code>.
<p/>
<ins>-?- <i>Throws:</i> Nothing.</ins>
<p/>
-4- <i>Remarks:</i> When <code>T</code> is <code>void</code>, it is unspecified whether this member function is declared. 
If it is declared, it is unspecified what its return type is, except that the declaration (although not necessarily the
definition) of the function shall be well formed.
</p>
</blockquote></blockquote>

<blockquote><pre>
T* operator-&gt;() const <del>noexcept</del>;
</pre><blockquote>
<p>
-5- <i>Requires:</i> <code>get() != 0</code>.
<p/>
-6- <i>Returns:</i> <code>get()</code>.
<p/>
<ins>-?- <i>Throws:</i> Nothing.</ins>
</p>
</blockquote></blockquote>
</li>

</ol>
</blockquote>

<p><i>[2015-03-03, Geoffrey provides rationale]</i></p>

<p>
<b>Rationale</b>:
</p>
<blockquote>
<p>
It is by design that these members are <code>noexcept</code>, and changing that now would be a substantial regression in functionality. 
These classes were designed to substitute for plain pointers as transparently as possible, so since those operations are effectively 
<code>noexcept</code> on plain pointers, they should be <code>noexcept</code> on <code>unique_ptr</code> and <code>shared_ptr</code> as well. 
This matters in practice because we expect these members to be used fairly often inside the <code>noexcept</code> operator, and such 
code could be broken by this change. These design considerations override our general policy against <code>noexcept</code> for 
narrow-contract functions.
<p/>
It is notable that N3279, which proposed this policy, did not propose striking <code>noexcept</code> from these operations. It's not 
clear if the omission of <code>operator*</code> and <code>operator-&gt;</code> was an oversight, or an intentional reflection of the above 
considerations. N3279 was based on N3248 by the same authors, which states that:
</p>
<blockquote>
<p>
"Most applications of <code>noexcept</code> for <code>unique_ptr</code> and <code>shared_ptr</code> are on functions with wide contracts. 
However, there are preconditions on the atomic access functions, so these should lose the specification."
</p>
</blockquote>
</blockquote>



<p id="res-2337"><b>Proposed resolution:</b></p>





</body>
</html>
