<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 3588: Strike out purposeless UB involving the deleter in members functions of unique_ptr</title>
<meta property="og:title" content="Issue 3588: Strike out purposeless UB involving the deleter in members functions of unique_ptr">
<meta property="og:description" content="C++ library issue. Status: NAD">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue3588.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="3588"><a href="lwg-closed.html#3588">3588</a>. Strike out purposeless UB involving the deleter in members functions of <code>unique_ptr</code></h3>
<p><b>Section:</b> 20.3.1.3.1 <a href="https://wg21.link/unique.ptr.single.general">[unique.ptr.single.general]</a> <b>Status:</b> <a href="lwg-active.html#NAD">NAD</a>
 <b>Submitter:</b> Johel Ernesto Guerrero Pe&ntilde;a <b>Opened:</b> 2021-09-07 <b>Last modified:</b> 2021-09-20</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all other</b> <a href="lwg-index.html#unique.ptr.single.general">issues</a> in [unique.ptr.single.general].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#NAD">NAD</a> status.</p>
<p><b>Discussion:</b></p>
<p>
This originated from the editorial issues <a href="https://github.com/cplusplus/draft/pull/4871">#4871</a> 
and <a href="https://github.com/cplusplus/draft/pull/4872">#4872</a>.
<p/>
Several member functions of <code>unique_ptr</code> are <code>noexcept</code>, and yet, they have the precondition 
that an expression involving the deleter does not exit via an exception. There's nothing an implementation 
or user can take advantage of in presence of this UB. Since the behavior otherwise would be a call to 
<code>std::terminate</code>, these preconditions should be striked out.
<p/>
Note that although <code>~unique_ptr()</code> is not <code>noexcept</code>, 16.4.6.14 <a href="https://wg21.link/res.on.exception.handling">[res.on.exception.handling]</a> p3 
specifies it to behave as if it were.
</p>
<p><i>[2021-09-20 Status changed: New &rarr; NAD.]</i></p>

<p>
The current specification allows the compiler to omit noexcept-enforcement.
</p>



<p id="res-3588"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/n4892">N4892</a>.
</p>

<ol>
<li><p>Modify 20.3.1.3.2 <a href="https://wg21.link/unique.ptr.single.ctor">[unique.ptr.single.ctor]</a> as indicated:</p>

<blockquote>
<pre>
constexpr unique_ptr() noexcept;
constexpr unique_ptr(nullptr_t) noexcept;
</pre>
<blockquote>
<p>
-1- [&hellip;]
<p/>
-2- <i>Preconditions:</i> <code>D</code> meets the <i>Cpp17DefaultConstructible</i> requirements (Table 27)<del>, 
and that construction does not throw an exception</del>.
<p/>
[&hellip;]
</p>
</blockquote>
<pre>
explicit unique_ptr(pointer p) noexcept;
</pre>
<blockquote>
<p>
-5- <i>Constraints:</i> [&hellip;]
<p/>
-6- <i>Mandates:</i> [&hellip;]
<p/>
-7- <i>Preconditions:</i> <code>D</code> meets the <i>Cpp17DefaultConstructible</i> requirements (Table 27)<del>, 
and that construction does not throw an exception</del>.
<p/>
[&hellip;]
</p>
</blockquote>
<pre>
unique_ptr(pointer p, const D&amp; d) noexcept;
unique_ptr(pointer p, remove_reference_t&lt;D&gt;&amp;&amp; d) noexcept;
</pre>
<blockquote>
<p>
-10- <i>Constraints:</i> [&hellip;]
<p/>
-11- <i>Mandates:</i> [&hellip;]
<p/>
-12- <i>Preconditions:</i> For the first constructor, if <code>D</code> is not a reference type, <code>D</code> 
meets the <i>Cpp17CopyConstructible</i> requirements <del>and such construction does not exit via an exception</del>. 
For the second constructor, if <code>D</code> is not a reference type, <code>D</code> meets the <i>Cpp17MoveConstructible</i> 
requirements <del>and such construction does not exit via an exception</del>.
<p/>
[&hellip;]
</p>
</blockquote>
<pre>
unique_ptr(unique_ptr&amp;&amp; u) noexcept;
</pre>
<blockquote>
<p>
-17- <i>Constraints:</i> [&hellip;]
<p/>
-18- <i>Preconditions:</i> If <code>D</code> is not a reference type, <code>D</code> meets the <i>Cpp17MoveConstructible</i> 
requirements (Table 28). <del>Construction of the deleter from an rvalue of type <code>D</code> does not throw an exception.</del>
<p/>
[&hellip;]
</p>
</blockquote>
<pre>
template&lt;class U, class E&gt; unique_ptr(unique_ptr&lt;U, E&gt;&amp;&amp; u) noexcept;
</pre>
<blockquote>
<p>
-21- <i>Constraints:</i> [&hellip;]
<p/>
-22- <i>Preconditions:</i> If <code>E</code> is not a reference type, construction of the deleter from an rvalue of type 
<code>E</code> is well-formed <del>and does not throw an exception</del>. Otherwise, <code>E</code> is a reference type and 
construction of the deleter from an lvalue of type <code>E</code> is well-formed <del>and does not throw an exception</del>.
<p/>
[&hellip;]
</p>
</blockquote>
</blockquote>
</li>

<li><p>Modify 20.3.1.3.3 <a href="https://wg21.link/unique.ptr.single.dtor">[unique.ptr.single.dtor]</a> as indicated:</p>

<blockquote>
<pre>
~unique_ptr();
</pre>
<blockquote>
<p>
-1- <i>Preconditions:</i> The expression <code>get_deleter()(get())</code> is well-formed<del>,</del>
<ins>and</ins> has well-defined behavior<del>, and does not throw exceptions</del>.
<p/>
[&hellip;]
</p>
</blockquote>
</blockquote>
</li>

<li><p>Modify 20.3.1.3.4 <a href="https://wg21.link/unique.ptr.single.asgn">[unique.ptr.single.asgn]</a> as indicated:</p>

<blockquote>
<pre>
unique_ptr&amp; operator=(unique_ptr&amp;&amp; u) noexcept;
</pre>
<blockquote>
<p>
-1- <i>Constraints:</i> [&hellip;]
<p/>
-2- <i>Preconditions:</i> If <code>D</code> is not a reference type, <code>D</code> meets the 
<i>Cpp17MoveAssignable</i> requirements (Table 30) <del>and assignment of the deleter from an 
rvalue of type <code>D</code> does not throw an exception</del>. Otherwise, <code>D</code> is a
reference type; <code>remove_reference_t&lt;D&gt;</code> meets the <i>Cpp17CopyAssignable</i> 
requirements <del>and assignment of the deleter from an lvalue of type <code>D</code> does not 
throw an exception</del>.
<p/>
[&hellip;]
</p>
</blockquote>
<pre>
template&lt;class U, class E&gt; unique_ptr&amp; operator=(unique_ptr&lt;U, E&gt;&amp;&amp; u) noexcept;
</pre>
<blockquote>
<p>
-6- <i>Constraints:</i> [&hellip;]
<p/>
-7- <i>Preconditions:</i> If <code>E</code> is not a reference type, assignment of the deleter from an rvalue 
of type <code>E</code> is well-formed <del>and does not throw an exception</del>. Otherwise, <code>E</code> is a 
reference type and assignment of the deleter from an lvalue of type <code>E</code> is well-formed <del>and 
does not throw an exception</del>.
<p/>
[&hellip;]
</p>
</blockquote>
</blockquote>
</li>

<li><p>Modify 20.3.1.3.6 <a href="https://wg21.link/unique.ptr.single.modifiers">[unique.ptr.single.modifiers]</a> as indicated:</p>

<blockquote>
<pre>
void reset(pointer p = pointer()) noexcept;
</pre>
<blockquote>
<p>
-3- <i>Preconditions:</i> The expression <code>get_deleter()(get())</code> is well-formed<del>,</del> 
<ins>and</ins> has well-defined behavior<del>, and does not throw exceptions</del>.
<p/>
[&hellip;]
</p>
</blockquote>
<pre>
void swap(unique_ptr&amp; u) noexcept;
</pre>
<blockquote>
<p>
-6- <i>Preconditions:</i> <code>get_deleter()</code> is swappable (16.4.4.3 <a href="https://wg21.link/swappable.requirements">[swappable.requirements]</a>) <del>and 
does not throw an exception under <code>swap</code></del>.
<p/>
[&hellip;]
</p>
</blockquote>
</blockquote>
</li>
</ol>





</body>
</html>
