<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 3008: make_shared (sub)object destruction semantics are not specified</title>
<meta property="og:title" content="Issue 3008: make_shared (sub)object destruction semantics are not specified">
<meta property="og:description" content="C++ library issue. Status: C++20">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue3008.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++20">C++20</a> status.</em></p>
<h3 id="3008"><a href="lwg-defects.html#3008">3008</a>. <code>make_shared</code> (sub)object destruction semantics are not specified</h3>
<p><b>Section:</b> 20.3.2.2.7 <a href="https://wg21.link/util.smartptr.shared.create">[util.smartptr.shared.create]</a> <b>Status:</b> <a href="lwg-active.html#C++20">C++20</a>
 <b>Submitter:</b> Glen Joseph Fernandes <b>Opened:</b> 2017-08-06 <b>Last modified:</b> 2021-02-25</p>
<p><b>Priority: </b>2
</p>
<p><b>View all other</b> <a href="lwg-index.html#util.smartptr.shared.create">issues</a> in [util.smartptr.shared.create].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#C++20">C++20</a> status.</p>
<p><b>Discussion:</b></p>
<p>
The remarks for the <code>make_shared</code> and <code>allocate_shared</code> functions 
do not specify how the objects managed by the returned <code>shared_ptr</code> are 
destroyed. It is implied that when objects are constructed via a placement new 
expression, they are destroyed by calling the destructor, and that when objects 
are constructed via an allocator, they are destroyed using that allocator. This 
should be explicitly specified.
</p>

<p><i>[2017-11 Albuquerque Wednesday night issues processing]</i></p>

<p>Priority set to 2</p>

<p><strong>Previous resolution [SUPERSEDED]:</strong></p>
<blockquote class="note">
<p>This resolution is relative to <a href="https://wg21.link/n4687">N4687</a>.</p>

<ol>
<li><p>Edit 20.3.2.2.7 <a href="https://wg21.link/util.smartptr.shared.create">[util.smartptr.shared.create]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class T, ...&gt;
shared_ptr&lt;T&gt; make_shared(<i>args</i>);
template&lt;class T, class A, ...&gt;
shared_ptr&lt;T&gt; allocate_shared(const A&amp; a, <i>args</i>);
</pre>
<blockquote>
<p>
[&hellip;]
<p/>
-7- <i>Remarks:</i>
</p>
<ol style="list-style-type: none">
<li><p>[&hellip;]</p></li>
<li><p>(7.9) &mdash; When the lifetime of the object managed by the return value ends, or when the initialization of
an array element throws an exception, the initialized elements should be destroyed in the reverse
order of their construction.</p></li>
<li><p><ins>(7.?) &mdash; When a (sub)object of a non-array type <code>U</code> that was initialized by
<code>make_shared</code> is to be destroyed, it shall be destroyed via the expression <code>pv-&gt;~U()</code> 
where <code>pv</code> points to that object of type <code>U</code>.</ins></p></li>
<li><p><ins>(7.?) &mdash; When a (sub)object of a non-array type <code>U</code> that was initialized by
<code>allocate_shared</code> is to be destroyed, it shall be destroyed via the expression 
<code>allocator_traits&lt;A2&gt;::destroy(a2, pv)</code> where <code>pv</code> points to that object of type 
<i>cv</i>-unqualified <code>U</code> and <code>a2</code> of type <code>A2</code> is a rebound copy of the allocator
<code>a</code> passed to <code>allocate_shared</code> such that its <code>value_type</code> is 
<code>remove_cv_t&lt;U&gt;</code>.</ins></p></li>
</ol>
</blockquote>
</blockquote>
</li>

</ol></blockquote>

<p><i>[2018-06 Rapperswil Wednesday night issues processing]</i></p>

<p>
CC: what is "of type <i>cv</i>-unqualified <code>U</code>" and "<code>remove_cv_T&lt;U&gt;</code>" about?<br/>
DK: again, it isn't new wording; it is in p 7.5.2<br/>
JW: but none of the words use "of type <i>cv</i>-unqualified <code>U</code>"<br/>
CT: so we should also used <code>remove_cv_T&lt;U&gt;</code> instead?<br/>
JW: I would like to talk to Glen<br/>
FB: does anybody know how it works for an array of arrays? It seems to cover the case<br/>
JW: we could leave it vague as it is now or specify it to exactly what it does<br/>
DK: I think we should split the thing into two parts and start with definitions<br/>
DK: ACTION I can refactor the wording<br/>
MC: there was a fairly long message thread when we talked about this 
<p/>
Daniel comments and improves wording:
<p/>
The currently allocator requirements support only the construction of <i>cv</i>-unqualified
object types (See Table 30 type <code>C</code> and pointer variable <code>c</code> as well as
Table 31 expressions "<code>a.construct(c, args)</code>" and "<code>a.destroy(c)</code>"), therefore a 
conforming implementation needs to effectively construct an object pointer that holds an object of type 
<code>remove_cv_T&lt;U&gt;</code> and similarly destroy such an object. Albeit it seems to be an artificial 
restriction to construct and destroy only non-<i>cv</i>-qualified object types, this is, if any, 
a different issue. But given this current state, the wording for <code>allocate_shared</code> needs 
to make a special wording dance via <code>remove_cv_T&lt;U&gt;</code>.
For <code>construct</code> the existing wording prevents to speak about that detail by using the more indirect
phrase "where <code>pv</code> points to storage suitable to hold an object of type <code>U</code>", but since
object types <code>U</code> and <code>const U</code> have exactly the same storage and alignment requirements,
this sentence is correct for <code>remove_cv_T&lt;U&gt;</code> as well.
</p>

<p><i>[2018-08-23 Batavia Issues processing]</i></p>

<p>Status to Tentatively Ready.</p>
<p><i>[2018-11, Adopted in San Diego]</i></p>



<p id="res-3008"><b>Proposed resolution:</b></p>
<p>This resolution is relative to <a href="https://wg21.link/n4750">N4750</a>.</p>

<ol>
<li><p>Edit 20.3.2.2.7 <a href="https://wg21.link/util.smartptr.shared.create">[util.smartptr.shared.create]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class T, ...&gt;
shared_ptr&lt;T&gt; make_shared(<i>args</i>);
template&lt;class T, class A, ...&gt;
shared_ptr&lt;T&gt; allocate_shared(const A&amp; a, <i>args</i>);
</pre>
<blockquote>
<p>
[&hellip;]
<p/>
-7- <i>Remarks:</i>
</p>
<ol style="list-style-type: none">
<li><p>[&hellip;]</p></li>
<li><p>(7.9) &mdash; When the lifetime of the object managed by the return value ends, or when the initialization of
an array element throws an exception, the initialized elements are destroyed in the reverse
order of their original construction.</p></li>
<li><p><ins>(7.?) &mdash; When a (sub)object of a non-array type <code>U</code> that was initialized by
<code>make_shared</code> is to be destroyed, it is destroyed via the expression <code>pv-&gt;~U()</code> 
where <code>pv</code> points to that object of type <code>U</code>.</ins></p></li>
<li><p><ins>(7.?) &mdash; When a (sub)object of a non-array type <code>U</code> that was initialized by
<code>allocate_shared</code> is to be destroyed, it is destroyed via the expression 
<code>allocator_traits&lt;A2&gt;::destroy(a2, pv)</code> where <code>pv</code> points to that object of type 
<code>remove_cv_t&lt;U&gt;</code> and <code>a2</code> of type <code>A2</code> is a rebound copy of the allocator
<code>a</code> passed to <code>allocate_shared</code> such that its <code>value_type</code> is 
<code>remove_cv_t&lt;U&gt;</code>.</ins></p></li>
</ol>
</blockquote>
</blockquote>
</li>

</ol>




</body>
</html>
