<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 3889: std::(ranges::)destroy_at should destroy array elements in the decreasing index order</title>
<meta property="og:title" content="Issue 3889: std::(ranges::)destroy_at should destroy array elements in the decreasing index order">
<meta property="og:description" content="C++ library issue. Status: New">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue3889.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#New">New</a> status.</em></p>
<h3 id="3889"><a href="lwg-active.html#3889">3889</a>. <code>std::(ranges::)destroy_at</code> should destroy array elements in the decreasing index order</h3>
<p><b>Section:</b> 26.11.9 <a href="https://wg21.link/specialized.destroy">[specialized.destroy]</a> <b>Status:</b> <a href="lwg-active.html#New">New</a>
 <b>Submitter:</b> Jiang An <b>Opened:</b> 2023-02-17 <b>Last modified:</b> 2023-03-22</p>
<p><b>Priority: </b>3
</p>
<p><b>View all issues with</b> <a href="lwg-status.html#New">New</a> status.</p>
<p><b>Discussion:</b></p>
<p>
Currently, <code>std::(ranges::)destroy_at</code> is specified to destroy array elements in the increasing index order 
(26.11.9 <a href="https://wg21.link/specialized.destroy">[specialized.destroy]</a>/1.1), which is inconsistent with the decreasing order specified in the core language 
(11.4.7 <a href="https://wg21.link/class.dtor">[class.dtor]</a>/13) and the order for arrays created by <code>std::make_shared</code> and 
<code>std::allocate_shared</code> (mandated by LWG <a href="lwg-defects.html#3005" title="Destruction order of arrays by make_shared/allocate_shared only recommended? (Status: C++20)">3005</a><sup><a href="https://cplusplus.github.io/LWG/issue3005" title="Latest snapshot">(i)</a></sup>).
</p>

<p><strong>Previous resolution [SUPERSEDED]:</strong></p>
<blockquote class="note">

<p>
This wording is relative to <a href="https://wg21.link/N4928" title=" Working Draft, Standard for Programming Language C++">N4928</a>.
</p>

<ol>

<li><p>Modify 26.11.9 <a href="https://wg21.link/specialized.destroy">[specialized.destroy]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class T&gt;
  constexpr void destroy_at(T* location);

namespace ranges {
  template&lt;destructible T&gt;
    constexpr void destroy_at(T* location) noexcept;
}
</pre>
<blockquote>
<p>
-1- <i>Effects:</i>
</p>
<ol style="list-style-type: none">
<li><p>(1.1) &mdash; If <code>T</code> is an array type, equivalent to <code>destroy(<ins>rbegin</ins><del>begin</del>(*location), <ins>rend</ins><del>end</del>(*location))</code>.</p></li>
<li><p>(1.2) &mdash; Otherwise, equivalent to <code>location-&gt;~T()</code>.</p></li>
</ol>
</blockquote>
</blockquote>

</li>

</ol>
</blockquote>

<p><i>[2023-02-26; Daniel comments and provides alternative wording]</i></p>

<p>
The suggested fix indeed corrects an inconsistency, but also implies a silent behaviour change at runtime, since at least MSVC STL and
libstdc++ implement the array destruction order as specified (others not tested). 
The below wording therefore suggests to introduce a specific feature macro for this, so that user code can potentially react on this,
regardless of potential vendor API breakage hesitations. 
The natural feature macro to increase would be that which introduced the specific array destruction behavior of <code>destroy_at</code>, 
which was <a href="https://wg21.link/P0896R4" title=" The One Ranges Proposal">P0896R4</a>, and which introduced <code>__cpp_lib_ranges</code>, on the other hand the specification change affects 
both the <code>std::ranges</code> and the <code>std</code> forms of <code>destroy_at</code>, so it seems plausible to suggest a new, specific feature 
macro for both <code>destroy_at</code> function templates. This is what the proposed wording does.
<p/>
LWG should clarify whether an entry to C.2 <a href="https://wg21.link/diff.cpp20">[diff.cpp20]</a> should be added as well.
</p>

<p><i>[2023-03-22; Reflector poll]</i></p>

<p>
Set priority to 3 after reflector poll.
</p>



<p id="res-3889"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4928" title=" Working Draft, Standard for Programming Language C++">N4928</a>.
</p>

<ol>

<li><p>Modify 17.3.2 <a href="https://wg21.link/version.syn">[version.syn]</a>, header <code>&lt;version&gt;</code> synopsis, as indicated and replace
the placeholder <code>YYYYMML</code> by the year and month of adoption of this issue:</p>

<blockquote>
<pre>
[&hellip;]
#define __cpp_lib_coroutine         201902L  // <i>also in &lt;coroutine&gt;</i>
<ins>#define __cpp_lib_destroy_at        YYYYMML  // <i>also in &lt;memory&gt;</i></ins>
#define __cpp_lib_destroying_delete 201806L  // <i>also in &lt;new&gt;</i>
[&hellip;]
</pre>
</blockquote>

</li>



<li><p>Modify 26.11.9 <a href="https://wg21.link/specialized.destroy">[specialized.destroy]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class T&gt;
  constexpr void destroy_at(T* location);

namespace ranges {
  template&lt;destructible T&gt;
    constexpr void destroy_at(T* location) noexcept;
}
</pre>
<blockquote>
<p>
-1- <i>Effects:</i>
</p>
<ol style="list-style-type: none">
<li><p>(1.1) &mdash; If <code>T</code> is an array type, equivalent to <code>destroy(<ins>rbegin</ins><del>begin</del>(*location), <ins>rend</ins><del>end</del>(*location))</code>.</p></li>
<li><p>(1.2) &mdash; Otherwise, equivalent to <code>location-&gt;~T()</code>.</p></li>
</ol>
</blockquote>
</blockquote>

</li>

</ol>





</body>
</html>
