<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 2468: Self-move-assignment of library types</title>
<meta property="og:title" content="Issue 2468: Self-move-assignment of library types">
<meta property="og:description" content="C++ library issue. Status: C++17">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue2468.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++17">C++17</a> status.</em></p>
<h3 id="2468"><a href="lwg-defects.html#2468">2468</a>. Self-move-assignment of library types</h3>
<p><b>Section:</b> 16.4.5.9 <a href="https://wg21.link/res.on.arguments">[res.on.arguments]</a>, 16.4.4.2 <a href="https://wg21.link/utility.arg.requirements">[utility.arg.requirements]</a>, 16.4.6.17 <a href="https://wg21.link/lib.types.movedfrom">[lib.types.movedfrom]</a>, 23.2.2 <a href="https://wg21.link/container.requirements.general">[container.requirements.general]</a> <b>Status:</b> <a href="lwg-active.html#C++17">C++17</a>
 <b>Submitter:</b> Matt Austern <b>Opened:</b> 2015-01-22 <b>Last modified:</b> 2017-07-30</p>
<p><b>Priority: </b>2
</p>
<p><b>View all other</b> <a href="lwg-index.html#res.on.arguments">issues</a> in [res.on.arguments].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#C++17">C++17</a> status.</p>
<p><b>Discussion:</b></p>
<p>
Suppose we write
</p>
<blockquote>
<pre>
vector&lt;string&gt; v{"a", "b", "c", "d"};
v = move(v);
</pre>
</blockquote>
<p>
What should be the state of <code>v</code> be? The standard doesn't say anything specific about self-move-assignment. 
There's relevant text in several parts of the standard, and it's not clear how to reconcile them.
<p/>
16.4.5.9 <a href="https://wg21.link/res.on.arguments">[res.on.arguments]</a> writes that, for all functions in the standard library, unless explicitly stated 
otherwise, "If a function argument binds to an rvalue reference parameter, the implementation may assume that this 
parameter is a unique reference to this argument." The <code>MoveAssignable</code> requirements table in 
16.4.4.2 <a href="https://wg21.link/utility.arg.requirements">[utility.arg.requirements]</a> writes that, given <code>t = rv</code>, <code>t</code>'s state is equivalent to 
<code>rv</code>'s from before the assignment and <code>rv</code>'s state is unspecified (but valid). For containers 
specifically, the requirements table in 23.2.2 <a href="https://wg21.link/container.requirements.general">[container.requirements.general]</a> says that, given <code>a = rv</code>, 
<code>a</code> becomes equal to what <code>rv</code> was before the assignment (and doesn't say anything about <code>rv</code>'s 
state post-assignment).
<p/>
Taking each of these pieces in isolation, without reference to the other two:
</p>
<ul>
<li><p>16.4.5.9 <a href="https://wg21.link/res.on.arguments">[res.on.arguments]</a> would clearly imply that the effect of <code>v = move(v)</code> is undefined.</p></li>
<li><p>16.4.4.2 <a href="https://wg21.link/utility.arg.requirements">[utility.arg.requirements]</a> would clearly imply that <code>v = move(v)</code> has defined behavior. 
It might be read to imply that this is a no-op, or might be read to imply that it leaves <code>v</code> in a valid but 
unspecified state; I'm not sure which reading is more natural.</p></li>
<li><p>23.2.2 <a href="https://wg21.link/container.requirements.general">[container.requirements.general]</a> would clearly imply that <code>v = move(v)</code> is a no-op.</p></li>
</ul>
<p>
It's not clear from the text how to put these pieces together, because it's not clear which one takes precedence.  
Maybe 16.4.5.9 <a href="https://wg21.link/res.on.arguments">[res.on.arguments]</a> wins (it imposes an implicit precondition that isn't mentioned in the 
<code>MoveAssignable</code> requirements, so <code>v = move(v)</code> is undefined), or maybe 
23.2.2 <a href="https://wg21.link/container.requirements.general">[container.requirements.general]</a> wins (it explicitly gives additional guarantees for 
<code>Container::operator=</code> beyond what's guaranteed for library functions in general, so <code>v = move(v)</code> 
is a no-op), or maybe something else.
<p/>
On the existing implementations that I checked, for what it's worth, <code>v = move(v)</code> appeared to clear the vector; 
it didn't leave the vector unchanged and it didn't cause a crash.
<p/>
<em>Proposed wording</em>:
<p/>
Informally: change the <code>MoveAssignable</code> and Container requirements tables (and any other requirements tables 
that mention move assignment, if any) to make it explicit that <code>x = move(x)</code> is defined behavior and it leaves 
<code>x</code> in a valid but unspecified state. That's probably not what the standard says today, but it's probably what 
we intended and it's consistent with what we've told users and with what implementations actually do.
</p>

<p><i>[2015-10, Kona Saturday afternoon]</i></p>

<p>JW: So far, the library forbids self-assignment since it assumes that anything bound to an rvalue reference has no aliases. But self-assignment can happen in real code, and it can be implemented. So I want to add an exception to the Standard that this should be allowed and leave the object in a valid-but-unspecified state.</p>
<p>STL: When this is resolved, I want to see a) VBU for library types after self-move, but also b) requirements on user types for self-moves. E.g. should algorithms be required to avoid self-assignments (since a user-defined type might blow up)? HH: In other words, should we require that you can assign from moved-from values.</p>
<p>WEB: What can one generally do with moved-from values?</p>
<p>VV: Call any member function that has no preconditions.</p>
<p>JW: That's certainly the library requirement, and it's also good guidance for user types.</p>
<p>JW: I'm writing wording. I care about this.</p>
<p>Move to Open; Jonathan to provide wording</p>

<p><i>[2016-08-01, Howard provided wording]</i></p>


<p><i>[2016-08 Chicago]</i></p>

<p>Tuesday AM: Move to Tentatively Ready</p>

<p>
<strong>Previous resolution [SUPERSEDED]:</strong>
</p>
<blockquote class="note">
<p>
In 16.4.4.3 <a href="https://wg21.link/swappable.requirements">[swappable.requirements]</a>, modify Table 23 &mdash; <code>MoveAssignable</code> requirements [moveassignable]:
</p>

<blockquote>

<table border="1">
<caption>Table 23 &mdash; <code>MoveAssignable</code> requirements [moveassignable]</caption>
<tr>
<th>Expression</th>
<th>Return type</th>
<th>Return value</th>
<th>Post-condition</th>
</tr>

<tr>
<td><code>t = rv</code></td>
<td><code>T&amp;</code></td>
<td><code>t</code></td>
<td><ins>If <code>addressof(t) != addressof(rv)</code>,</ins> <code>t</code> is
equivalent to the value of <code>rv</code> before the assignment</td>
</tr>

<tr>
<td colspan="4">
<code>rv</code>'s state is unspecified. [<i>Note:</i> <code>rv</code> must
still meet the requirements of the library component that is using it<ins>,
whether or not <code>addressof(t) == addressof(rv)</code></ins>. The
operations listed in those requirements must work as specified whether
<code>rv</code> has been moved from or not. &mdash; <i>end note</i>] </td>
</tr>

</table>

</blockquote>

</blockquote>

<p><i>[2016-08-07, Daniel reopens]</i></p>

<p>
With the acceptance of LWG <a href="lwg-defects.html#2598" title="addressof works on temporaries (Status: C++17)">2598</a><sup><a href="https://cplusplus.github.io/LWG/issue2598" title="Latest snapshot">(i)</a></sup>, the proposed wording is invalid code, because it attempts to
call <code>std::addressof</code> with an rvalue argument. It should be pointed out that the new restriction 
caused by <a href="lwg-defects.html#2598" title="addressof works on temporaries (Status: C++17)">2598</a><sup><a href="https://cplusplus.github.io/LWG/issue2598" title="Latest snapshot">(i)</a></sup> doesn't affect real code, because any identity test within a move assignment
operator (or any comparable function) would act on the current function argument, which is an lvalue in the
context of the function body. The existing wording form of the issue could still be kept, if a helper variable
would be introduced such as:
</p>
<blockquote><p>
<ins>Let <code>refrv</code> denote a reference initialized as if by <code>const T&amp; refrv = rv;</code>. Then 
if <code>addressof(t) != addressof(refrv)</code>,</ins> <code>t</code> is equivalent to the value of <code>rv</code> 
before the assignment
</p></blockquote>
<p>
But it seems to me that the same effect could be much easier realized by replacing the code form by 
a non-code English phrase that realizes the same effect.
</p>

<p><i>[2016-09-09 Issues Resolution Telecon]</i></p>

<p>Move to Tentatively Ready</p>

<p><i>[2016-10-05, Tim Song comments]</i></p>

<p>
The current P/R of LWG 2468 simply adds to <code>MoveAssignable</code> the requirement to tolerate self-move-assignment, 
but that doesn't actually do much about self-move-assignment of library types. Very few types in the library are 
explicitly required to satisfy <code>MoveAssignable</code>, so as written the restriction in 16.4.5.9 <a href="https://wg21.link/res.on.arguments">[res.on.arguments]</a> 
would seem to still apply for any type that's not explicitly required to be <code>CopyAssignable</code> or <code>MoveAssignable</code>.
<p/>
The current P/R also doesn't address the issue with 23.2.2 <a href="https://wg21.link/container.requirements.general">[container.requirements.general]</a> noted in the issue discussion.
</p>


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

<ol>
<li><p> In 16.4.4.3 <a href="https://wg21.link/swappable.requirements">[swappable.requirements]</a>, modify Table 23 &mdash; <code>MoveAssignable</code> 
requirements [moveassignable]:</p>

<blockquote>

<table border="1">
<caption>Table 23 &mdash; <code>MoveAssignable</code> requirements [moveassignable]</caption>
<tr>
<th>Expression</th>
<th>Return type</th>
<th>Return value</th>
<th>Post-condition</th>
</tr>

<tr>
<td><code>t = rv</code></td>
<td><code>T&amp;</code></td>
<td><code>t</code></td>
<td><ins>If <code>t</code> and <code>rv</code> do not refer to the same object,</ins> <code>t</code> is
equivalent to the value of <code>rv</code> before the assignment</td>
</tr>

<tr>
<td colspan="4">
<code>rv</code>'s state is unspecified. [<i>Note:</i> <code>rv</code> must
still meet the requirements of the library component that is using it<ins>,
whether or not <code>t</code> and <code>rv</code> refer to the same object</ins>. The
operations listed in those requirements must work as specified whether
<code>rv</code> has been moved from or not. &mdash; <i>end note</i>] </td>
</tr>

</table>

</blockquote>
</li>
</ol>





</body>
</html>
