<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 2262: Requirement for unique_ptr&lt;T&gt;::get_deleter()(p) to be able to destroy the unique_ptr</title>
<meta property="og:title" content="Issue 2262: Requirement for unique_ptr&lt;T&gt;::get_deleter()(p) to be able to destroy the unique_ptr">
<meta property="og:description" content="C++ library issue. Status: Open">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue2262.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#Open">Open</a> status.</em></p>
<h3 id="2262"><a href="lwg-active.html#2262">2262</a>. Requirement for <code>unique_ptr&lt;T&gt;::get_deleter()(p)</code> to be able to destroy the <code>unique_ptr</code></h3>
<p><b>Section:</b> 20.3.1.3 <a href="https://wg21.link/unique.ptr.single">[unique.ptr.single]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a>
 <b>Submitter:</b> Rob Desbois <b>Opened:</b> 2013-05-15 <b>Last modified:</b> 2017-03-21</p>
<p><b>Priority: </b>3
</p>
<p><b>View other</b> <a href="lwg-index-open.html#unique.ptr.single">active issues</a> in [unique.ptr.single].</p>
<p><b>View all other</b> <a href="lwg-index.html#unique.ptr.single">issues</a> in [unique.ptr.single].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#Open">Open</a> status.</p>
<p><b>Discussion:</b></p>
<p>
N3337 20.3.1.3.6 <a href="https://wg21.link/unique.ptr.single.modifiers">[unique.ptr.single.modifiers]</a> contains 2 non-normative notes stating:
</p>

<blockquote>
<p>
[para 4]: &quot;The order of these operations is significant because the call to <code>get_deleter()</code> 
may destroy <code>*this</code>.&quot;
</p>
<p>
[para 5]: &quot;The postcondition does not hold if the call to <code>get_deleter()</code> destroys <code>*this</code> since 
<code>this->get()</code> is no longer a valid expression.&quot;
</p>
</blockquote>

<p>
It seems this wording was created to resolve <a href="lwg-defects.html#998" title="Smart pointer referencing its owner (Status: C++11)">998</a><sup><a href="https://cplusplus.github.io/LWG/issue998" title="Latest snapshot">(i)</a></sup> due to the possibility that a <code>unique_ptr</code> may be 
destroyed through deletion of its stored pointer where that directly or indirectly refers to the same <code>unique_ptr</code>. 
If <code>unique_ptr</code> is required to support circular references then it seems this must be normative text: an implementation 
is currently allowed to operate on <code>*this</code> after the assignment and deletion specified in para 4, since this is only 
'disallowed' by the non-normative note.
</p>

<p>I propose the following draft rewording:</p>

<p>
[para 4]: <i>Effects</i>: assigns <code>p</code> to the stored pointer, and then if the old value of the stored pointer, <code>old_p</code>, was not
equal to <code>nullptr</code>, calls <code>get_deleter()(old_p)</code>. <ins>No operation shall be performed after the call to 
<code>get_deleter()(old_p)</code> that requires <code>*this</code> to be valid, because the deletion may destroy <code>*this</code> if it is 
referred to directly or indirectly by the stored pointer.</ins> <del>[<i>Note:</i> The order of these operations is significant
because the call to <code>get_deleter()</code> may destroy <code>*this</code>. &mdash; <i>end note</i>]</del>
<p/>
[para 5]: <i>Postconditions</i>: <ins>If the call <code>get_deleter()(old_p)</code> destroyed <code>*this</code>, none. Otherwise,</ins> 
<code>get() == p</code>. <del>[<i>Note:</i> The postcondition does not hold if the call to <code>get_deleter()</code>
destroys <code>*this</code> since <code>this->get()</code> is no longer a valid expression. &mdash; <i>end note</i>]</del>
</p>

<p>
I expect it will also be necessary to amend the requirements for a deleter, so in addition:
</p>

<p>
20.3.1.3 <a href="https://wg21.link/unique.ptr.single">[unique.ptr.single]</a> [para 1]: The default type for the template parameter <code>D</code> is <code>default_delete</code>. 
A client-supplied template argument <code>D</code> shall be a function object type (20.10), lvalue-reference to function, or 
lvalue-reference to function object type for which, given a value <code>d</code> of type <code>D</code> and a value <code>ptr</code> of type 
<code>unique_ptr&lt;T, D&gt;::pointer</code>, the expression <code>d(ptr)</code> is valid and has the effect of disposing of the pointer 
as appropriate for that deleter. <ins>Where <code>D</code> is not an lvalue reference type, <code>d(ptr)</code> shall be valid if <code>ptr</code> 
refers directly or indirectly to the invoking <code>unique_ptr</code> object.</ins>
</p>

<p><i>[2013-10-05, Stephan T. Lavavej comments and provides alternative wording]</i></p>

<p>
In Chicago, we determined that the original proposed change to 20.3.1.3 <a href="https://wg21.link/unique.ptr.single">[unique.ptr.single]</a>/1 was insufficient, because 
<code>d</code> might be a reference to a deleter functor that's destroyed during self-destruction.
<p/>
We believed that 20.3.1.3.6 <a href="https://wg21.link/unique.ptr.single.modifiers">[unique.ptr.single.modifiers]</a>/4 was already sufficiently clear. The Standard occasionally prevents 
implementations of <code>X</code> from doing various things, through the principle of "nothing allows <code>X</code> to fail in that situation".  
For example, <code>v.push_back(v[0])</code> is required to work for non-empty vectors because nothing allows that to fail. In this case, 
the intent to allow self-destruction is already clear.
<p/>
Additionally, we did not believe that 20.3.1.3.6 <a href="https://wg21.link/unique.ptr.single.modifiers">[unique.ptr.single.modifiers]</a>/5 had to be changed. The current note is slightly 
squirrely but it does not lead to confusion for implementers or users.
</p>

<p>
Previous resolution from Rob Desbois:
</p>
<blockquote class="note">
<ol>
<li>
<p>
Edit 20.3.1.3 <a href="https://wg21.link/unique.ptr.single">[unique.ptr.single]</a> p1 as indicated:
</p>
<blockquote><p>
The default type for the template parameter <code>D</code> is <code>default_delete</code>. 
A client-supplied template argument <code>D</code> shall be a function object type (20.10), lvalue-reference to function, or 
lvalue-reference to function object type for which, given a value <code>d</code> of type <code>D</code> and a value <code>ptr</code> of type 
<code>unique_ptr&lt;T, D&gt;::pointer</code>, the expression <code>d(ptr)</code> is valid and has the effect of disposing of the pointer 
as appropriate for that deleter. <ins>Where <code>D</code> is not an lvalue reference type, <code>d(ptr)</code> shall be valid if <code>ptr</code> 
refers directly or indirectly to the invoking <code>unique_ptr</code> object.</ins>
</p></blockquote>
</li>

<li>
<p>
Edit 20.3.1.3.6 <a href="https://wg21.link/unique.ptr.single.modifiers">[unique.ptr.single.modifiers]</a> p4+5 as indicated:
</p>
<blockquote><pre>
void reset(pointer p = pointer()) noexcept;
</pre><blockquote>
<p>
-3- <i>Requires:</i> The expression <code>get_deleter()(get())</code> shall be well formed, shall have well-defined behavior,
and shall not throw exceptions.
<p/>
-4- <i>Effects:</i> assigns <code>p</code> to the stored pointer, and then if the old value of the stored pointer, <code>old_p</code>, was not
equal to <code>nullptr</code>, calls <code>get_deleter()(old_p)</code>. <ins>No operation shall be performed after the call to 
<code>get_deleter()(old_p)</code> that requires <code>*this</code> to be valid, because the deletion may destroy <code>*this</code> if it is 
referred to directly or indirectly by the stored pointer.</ins> <del>[<i>Note:</i> The order of these operations is significant
because the call to <code>get_deleter()</code> may destroy <code>*this</code>. &mdash; <i>end note</i>]</del>
<p/>
-5- <i>Postconditions:</i> <ins>If the call <code>get_deleter()(old_p)</code> destroyed <code>*this</code>, none. Otherwise,</ins> 
<code>get() == p</code>. <del>[<i>Note:</i> The postcondition does not hold if the call to <code>get_deleter()</code>
destroys <code>*this</code> since <code>this->get()</code> is no longer a valid expression. &mdash; <i>end note</i>]</del>
</p>
</blockquote></blockquote>
</li>
</ol>

</blockquote>

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

<ol>
<li>
<p>
Edit 20.3.1.3 <a href="https://wg21.link/unique.ptr.single">[unique.ptr.single]</a> p1 as indicated:
</p>
<blockquote><p>
The default type for the template parameter <code>D</code> is <code>default_delete</code>. 
A client-supplied template argument <code>D</code> shall be a function object type (20.10), lvalue-reference to function, or 
lvalue-reference to function object type for which, given a value <code>d</code> of type <code>D</code> and a value <code>ptr</code> of type 
<code>unique_ptr&lt;T, D&gt;::pointer</code>, the expression <code>d(ptr)</code> is valid and has the effect of disposing of the pointer 
as appropriate for that deleter. <ins><code>d(ptr)</code> shall be valid even if it triggers the destruction of <code>d</code> or (if 
<code>D</code> is an lvalue reference to function object type) the function object that <code>d</code> refers to.</ins>
</p></blockquote>
</li>
</ol>
</blockquote>

<p><i>[2015-05, Lenexa]</i></p>

<p>
After some discussion in Lenexa there was some wavering on if the added sentence is necessary. Here is example code that 
demonstrates why the extra sentence is necessary. In this example the call to <code>d(ptr)</code> is valid, however the deleter 
references <code>*this</code> after destructing its element:
</p>
<blockquote><pre>
#include &lt;cassert&gt;
#include &lt;memory&gt;
#include &lt;iostream&gt;

class Deleter
{
    int state_ = 0;

    enum
    {
        destructed            = -4,
        self_move_assigned    = -3,
        move_assigned_from    = -2,
        move_constructed_from = -1
    };
public:
    ~Deleter() {state_ = destructed;}

    Deleter() = default;
    Deleter(Deleter const&amp;) = default;
    Deleter&amp; operator=(Deleter const&amp;) = default;

    Deleter(Deleter&amp;&amp; a) noexcept
        : state_(a.state_)
    {a.state_ = move_constructed_from;}

    Deleter&amp; operator=(Deleter&amp;&amp; a) noexcept
    {
        if (this == &amp;a)
            state_ = self_move_assigned;
        else
        {
            state_ = a.state_;
            a.state_ = move_assigned_from;
        }
        return *this;
    }

    Deleter(int state)
        : state_(state)
    {
        assert(state &gt;= 0);
    }

    template &lt;class T&gt;
    void
    operator()(T* t) const
    {
        std::cout &lt;&lt; "Deleter beginning operator()(T*)\n";
        std::cout &lt;&lt; "The deleter = " &lt;&lt; *this &lt;&lt; '\n';
        std::cout &lt;&lt; "Deleter about to destruct the X.\n";
        delete t;
        std::cout &lt;&lt; "Deleter has destructed the X.\n";
        std::cout &lt;&lt; "The deleter = " &lt;&lt; *this &lt;&lt; '\n';
        std::cout &lt;&lt; "Deleter ending operator()(T*)\n";
    }

    friend
    std::ostream&amp;
    operator&lt;&lt;(std::ostream&amp; os, const Deleter&amp; a)
    {
        switch (a.state_)
        {
        case destructed:
            os &lt;&lt; "**destructed**";
            break;
        case self_move_assigned:
            os &lt;&lt; "self_move_assigned";
            break;
        case move_assigned_from:
            os &lt;&lt; "move_assigned_from";
            break;
        case move_constructed_from:
            os &lt;&lt; "move_constructed_from";
            break;
        default:
            os &lt;&lt; a.state_;
            break;
        }
        return os;
    }
};

struct X
{
    Deleter deleter_{1};
};

int main()
{
    auto xp = new X;
    {
        std::unique_ptr&lt;X, Deleter&amp;&gt; p(xp, xp-&gt;deleter_);
        std::cout &lt;&lt; "unique_ptr is constructed.\n";
        std::cout &lt;&lt; "The deleter = " &lt;&lt; p.get_deleter() &lt;&lt; '\n';
        std::cout &lt;&lt; "Destructing unique_ptr...\n";
    }
    std::cout &lt;&lt; "unique_ptr is destructed.\n";
}
</pre></blockquote>
<p>
Which outputs:
</p>
<blockquote>
<pre>
unique_ptr is constructed.
The deleter = 1
Destructing unique_ptr...
Deleter beginning operator()(T*)
The deleter = 1
Deleter about to destruct the X.
Deleter has destructed the X.
The deleter = **destructed**
Deleter ending operator()(T*)
unique_ptr is destructed.
</pre>
</blockquote>
<p>
The line "<code>The deleter = **destructed**</code>" represents the deleter referencing itself after it has been destructed by the 
<code>d(ptr)</code> expression, but prior to that call returning.
<p/>
Suggested alternative to the current proposed wording:
</p>
<blockquote>
<p>
The expression <code>d(ptr)</code> shall not refer to the object <code>d</code> after it executes <code>ptr-&gt;~T()</code>.
</p>
</blockquote>

<p><i>[2015-07, Telecon]</i></p>

<p>
Geoffrey: Deleter may or may not execute ~T().<br/>
Alisdair: After the destructor after the element has run. Say it in words instead of code. <br/>
Howard will provide updated wording. Perhaps need both normative and non-normative wording.<br/>
</p>

<p><i>[2015-08-03, Howard updates P/R per telecon discussion.]</i></p>


<p><i>[2017-03-04, Kona]</i></p>

<p>This is related to <a href="lwg-active.html#2751" title="shared_ptr deleter not specified to observe expired weak_ptr instances (Status: New)">2751</a><sup><a href="https://cplusplus.github.io/LWG/issue2751" title="Latest snapshot">(i)</a></sup>, which has been suggested NAD.</p>
<p>STL wants "Effects equivalent to" here - say it in code.  Marshall to research.</p>


<p id="res-2262"><b>Proposed resolution:</b></p>
<p>This wording is relative to N4431.</p>

<ol>
<li>
<p>
Edit 20.3.1.3 <a href="https://wg21.link/unique.ptr.single">[unique.ptr.single]</a> p1 as indicated:
</p>
<blockquote><p>
The default type for the template parameter <code>D</code> is <code>default_delete</code>. 
A client-supplied template argument <code>D</code> shall be a function object type (20.9), lvalue-reference to function, or 
lvalue-reference to function object type for which, given a value <code>d</code> of type <code>D</code> and a value <code>ptr</code> of type 
<code>unique_ptr&lt;T, D&gt;::pointer</code>, the expression <code>d(ptr)</code> is valid and has the effect of disposing of the pointer 
as appropriate for that deleter. <ins>The expression <code>d(ptr)</code>, if it destructs the object referred to by <code>ptr</code>,
shall not refer to the object <code>d</code> after it destructs <code>*ptr</code>.
[<i>Note:</i> The object being destructed may control the lifetime of <code>d</code>. &mdash; <i>end note</i>]</ins>
</p></blockquote>
</li>
</ol>






</body>
</html>
