title: Is delete allowed to modify its parameter?
body: <p>In an answer, <a href="https://stackoverflow.com/a/704568/8157187">https://stackoverflow.com/a/704568/8157187</a>, there is a quote from Stroustrup:</p>
  
  <blockquote>
    <p>C++ explicitly allows an implementation of delete to zero out an
    lvalue operand, and I had hoped that implementations would do that,
    but that idea doesn't seem to have become popular with implementers.</p>
  </blockquote>
  
  <p>However, I failed to find this explicit statement in the standard. There is a part of the current draft standard (N4659), that one may interpret this way:</p>
  
  <p>6.7:</p>
  
  <blockquote>
    <p>When the end of the duration of a region of storage is reached, the
    values of all pointers representing the address of any part of that
    region of storage become invalid pointer values (6.9.2). Indirection
    through an invalid pointer value and passing an invalid pointer value
    to a deallocation function have undeﬁned behavior. Any other use of an
    invalid pointer value has implementation-deﬁned behavior.</p>
    
    <p>Footnote: Some implementations might deﬁne that copying an invalid pointer value causes a system-generated runtime fault</p>
  </blockquote>
  
  <p>So, after a <code>delete ptr;</code>, <code>ptr</code>'s value becomes a invalid pointer value, and using this value has implementation-defined behavior. However, it doesn't say that <code>ptr</code>'s value is allowed to change.</p>
  
  <p>It might be a philosophical question, how can one decide that a value has changed, if one cannot use its value?</p>
  
  <p>6.9:</p>
  
  <blockquote>
    <p>For any object (other than a base-class subobject) of trivially
    copyable type T, whether or not the object holds a valid value of type
    T, the underlying bytes (4.4) making up the object can be copied into
    an array of char, unsigned char, or std::byte (21.2.1).43 If the
    content of that array is copied back into the object, the object shall
    subsequently hold its original value.</p>
  </blockquote>
  
  <p>So, it seems, that it is valid to <code>memcpy</code> an invalid pointer value into a char array (depending on which statement is "stronger", 6.7 or 6.9. To me, 6.9 seems stronger).</p>
  
  <p>This way, I can detect, that the pointer value has been changed by <code>delete</code>: <code>memcpy</code> the pointer's value before and after the <code>delete</code> to char array, then compare them.</p>
  
  <p>So, as I understand, 6.7 doesn't grant that <code>delete</code> is allowed to modify its parameter.</p>
  
  <p>Is delete allowed to modify its parameter?</p>
  
  <p>Check out the comments here:
  <a href="https://stackoverflow.com/a/45142972/8157187">https://stackoverflow.com/a/45142972/8157187</a></p>
  
  <hr>
  
  <p>Here's an unlikely, but still possible real-world code, where this matters:</p>
  
  <pre><code>SomeObject *o = ...; // We have a SomeObject
  // This SomeObject is registered into someHashtable, with its memory address
  // The hashtable interface is C-like, it handles opaque keys (variable length unsigned char arrays)
  
  delete o;
  
  unsigned char key[sizeof(o)];
  memcpy(key, &amp;o, sizeof(o)); // Is this line OK? Is its behavior implementation defined?
  someHashtable.remove(key, sizeof(key)); // Remove o from the hashtable
  </code></pre>
  
  <p>Of course, this snippet can be reordered, so it becomes a surely valid code. But the question is: is this a valid code?</p>
  
  <hr>
  
  <p>Here's a related train of thought: suppose, that an implementation does define what footnote describes:</p>
  
  <blockquote>
    <p>copying an invalid pointer value causes a system-generated runtime fault</p>
  </blockquote>
  
  <p>6.9 guarantees that I can <code>memcpy()</code> any value. Even an invalid one. So in this theoretical implementation, when I <code>memcpy()</code> the invalid pointer value (which should succeed, 6.9 guarantees that), in a sense, I don't use the invalid pointer value, but only its underlying bytes (because it would generate a runtime fault, and 6.9 doesn't allow it), <strong>so 6.7 doesn't apply</strong>.</p>