<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 3789: Precondition of (not replaced) operator delete[]</title>
<meta property="og:title" content="Issue 3789: Precondition of (not replaced) operator delete[]">
<meta property="og:description" content="C++ library issue. Status: NAD">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue3789.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="3789"><a href="lwg-closed.html#3789">3789</a>. Precondition of (not replaced) <code>operator delete[]</code></h3>
<p><b>Section:</b> 17.6.3.3 <a href="https://wg21.link/new.delete.array">[new.delete.array]</a> <b>Status:</b> <a href="lwg-active.html#NAD">NAD</a>
 <b>Submitter:</b> blacktea hamburger <b>Opened:</b> 2022-09-25 <b>Last modified:</b> 2022-11-30</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all other</b> <a href="lwg-index.html#new.delete.array">issues</a> in [new.delete.array].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#NAD">NAD</a> status.</p>
<p><b>Discussion:</b></p>
<p>
Consider (<code>operator delete[](std::size_t)</code> and <code>operator new(std::size_t)</code> is not replaced):
</p>
<blockquote><pre>
operator delete[](operator new(1));
</pre></blockquote>
<p>
(even not replaced) <code>void* operator new(std::size_t)</code> does not return 
<code>void* operator new[](std::size_t)</code>. So the behavior is undefined according 
to 17.6.3.3 <a href="https://wg21.link/new.delete.array">[new.delete.array]</a> paragraph 9:
</p>
<blockquote><p>
<i>Preconditions</i>: <code>ptr</code> is a null pointer or its value represents the address of a block of 
memory allocated by an earlier call to a (possibly replaced) <code>operator new[](std::size_t)</code> or 
<code>operator new[](std::size_t, std::align_val_t)</code> which has not been invalidated by an intervening 
call to <code>operator delete[]</code>.
</p></blockquote>
<p>
However, consider (<code>operator delete(std::size_t)</code> and <code>operator new[](std::size_t)</code> is not replaced):
</p>
<blockquote><pre>
operator delete(operator new[](1));
</pre></blockquote>
<p>
(not replaced) <code>operator new[](std::size_t)</code> simply returns <code>operator new(std::size_t)</code> 
according to 17.6.3.3 <a href="https://wg21.link/new.delete.array">[new.delete.array]</a> paragraph 4:
</p>
<blockquote><p>
<i>Default behavior</i>: Returns <code>operator new(size)</code>, or <code>operator new(size, alignment)</code>, respectively.
</p></blockquote>
<p>
So it is well-formed according to 17.6.3.2 <a href="https://wg21.link/new.delete.single">[new.delete.single]</a> paragraph 10:
</p>
<blockquote><p>
<i>Preconditions</i>: <code>ptr</code> is a null pointer or its value represents the address of a block of memory 
allocated by an earlier call to a (possibly replaced) <code>operator new(std::size_t)</code> or 
<code>operator new(std::size_t, std::align_val_t)</code> which has not been invalidated by an intervening call to 
<code>operator delete</code>.
</p></blockquote>
<p>
The behavior should be consistent.
</p>

<p><i>[2022-10-10; Reflector poll]</i></p>

<p>Set status to "Tentatively NAD" after reflector poll.</p>
<p>
"No reason to carve out an exception covering a case on something which can’t
be observed by the program (whether the allocation operators are replaced).
This just makes things more complicated for no good reason."
"This would require changes to sanitizers and other dynamic analyzers,
for zero practical benefit (except allowing bad code to go un-diagnosed)."
</p>

<p><i>[2022-11-30 LWG telecon. Status changed: Tentatively NAD &rarr; NAD.]</i></p>



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

<ol>
<li><p>Modify 17.6.3.3 <a href="https://wg21.link/new.delete.array">[new.delete.array]</a> as indicated:</p>

<blockquote>
<pre>
void operator delete[](void* ptr) noexcept;
void operator delete[](void* ptr, std::size_t size) noexcept;
void operator delete[](void* ptr, std::align_val_t alignment) noexcept;
void operator delete[](void* ptr, std::size_t size, std::align_val_t alignment) noexcept;
</pre>
<blockquote>
<p>
-9- <i>Preconditions</i>: <code>ptr</code> is a null pointer or its value represents the address 
of a block of memory allocated by an earlier call to a (possibly replaced) 
<code>operator new[](std::size_t)</code><ins>,</ins> <del>or</del> 
<code>operator new[](std::size_t, std::align_val_t)</code><ins>, (not replaced) 
<code>operator new(std::size_t)</code>, or <code>operator new(std::size_t, std::align_val_t)</code></ins>
which has not been invalidated by an intervening call to <code>operator delete[]</code>.
<p/>
[&hellip;]
</p>
</blockquote>
</blockquote>
</li>
</ol>





</body>
</html>
