<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 910: Effects of MoveAssignable</title>
<meta property="og:title" content="Issue 910: Effects of MoveAssignable">
<meta property="og:description" content="C++ library issue. Status: NAD Concepts">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue910.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_Concepts">NAD Concepts</a> status.</em></p>
<h3 id="910"><a href="lwg-closed.html#910">910</a>. Effects of MoveAssignable</h3>
<p><b>Section:</b> 16.4.4.2 <a href="https://wg21.link/utility.arg.requirements">[utility.arg.requirements]</a> <b>Status:</b> <a href="lwg-active.html#NAD_Concepts">NAD Concepts</a>
 <b>Submitter:</b> Alberto Ganesh Barbati <b>Opened:</b> 2008-09-29 <b>Last modified:</b> 2016-01-28</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View other</b> <a href="lwg-index-open.html#utility.arg.requirements">active issues</a> in [utility.arg.requirements].</p>
<p><b>View all other</b> <a href="lwg-index.html#utility.arg.requirements">issues</a> in [utility.arg.requirements].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#NAD Concepts">NAD Concepts</a> status.</p>
<p><b>Discussion:</b></p>
<p><b>Addresses UK 150</b></p>

<p>
The description of the effect of <code>operator=</code> in the <code>MoveAssignable</code>
concept, given in paragraph 7 is:
</p>

<blockquote><pre>
result_type  T::operator=(T&amp;&amp;  rv);  // inherited from HasAssign&lt;T, T&amp;&amp;&gt;
</pre>

<blockquote><p>
<i>Postconditions:</i> the constructed <code>T</code> object is equivalent to the value of
<code>rv</code> before the assignment. [<i>Note:</i> there is no
requirement on the value of <code>rv</code> after the assignment.  <i>--end note</i>]
</p></blockquote>
</blockquote>

<p>
The sentence contains a typo (what is the "constructed <code>T</code> object"?)
probably due to a cut&amp;paste from <code>MoveConstructible</code>. Moreover, the
discussion of LWG issue <a href="lwg-defects.html#675" title="Move assignment of containers (Status: CD1)">675</a><sup><a href="https://cplusplus.github.io/LWG/issue675" title="Latest snapshot">(i)</a></sup> shows that the postcondition is too generic
and might not reflect the user expectations. An implementation of the
move assignment that just calls <code>swap()</code> would always fulfill the
postcondition as stated, but might have surprising side-effects in case
the source rvalue refers to an object that is not going to be
immediately destroyed. See LWG issue <a href="lwg-defects.html#900" title="Stream move-assignment (Status: C++11)">900</a><sup><a href="https://cplusplus.github.io/LWG/issue900" title="Latest snapshot">(i)</a></sup> for another example. Due to
the sometimes intangible nature of the "user expectation", it seems
difficult to have precise normative wording that could cover all cases
without introducing unnecessary restrictions. However a non-normative
clarification could be a very helpful warning sign that swapping is not
always the correct thing to do.
</p>

<p><i>[
2009-05-09 Alisdair adds:
]</i></p>


<blockquote>
<p>
Issue 910 is exactly the reason BSI advanced the Editorial comment UK-150.
</p>
<p>
The post-conditions after assignment are at a minimum that the object
referenced by rv must be safely destructible, and the transaction should not
leak resources.  Ideally it should be possible to simply assign rv a new
valid state after the call without invoking undefined behaviour, but any
other use of the referenced object would depend upon additional guarantees
made by that type.
</p>
</blockquote>

<p><i>[
2009-05-09 Howard adds:
]</i></p>


<blockquote>
<p>
The intent of the rvalue reference work is that the moved from <code>rv</code> is
a valid object.  Not one in a singular state.  If, for example, the moved from
object is a <code>vector</code>, one should be able to do anything on that moved-from
<code>vector</code> that you can do with any other <code>vector</code>.  However you would
first have to query it to find out what its current state is.  E.g. it might have <code>capacity</code>,
it might not.  It might have a non-zero <code>size</code>, it might not.  But regardless,
you can <code>push_back</code> on to it if you want.
</p>

<p>
That being said, most standard code is now conceptized.  That is, the concepts
list the only operations that can be done with templated types - whether or not
the values have been moved from.
</p>

<p>
Here is user-written code which must be allowed to be legal:
</p>
<blockquote><pre>
#include &lt;vector&gt;
#include &lt;cstdio&gt;

template &lt;class Allocator&gt;
void
inspect(std::vector&lt;double, Allocator&gt;&amp;&amp; v)
{
    std::vector&lt;double, Allocator&gt; result(move(v));
    std::printf("moved from vector has %u size and %u capacity\n", v.size(), v.capacity());
    std::printf("The contents of the vector are:\n");
    typedef typename std::vector&lt;double, Allocator&gt;::iterator I;
    for (I i = v.begin(), e = v.end(); i != e; ++i)
        printf("%f\n", *i);
}

int main()
{
    std::vector&lt;double&gt; v1(100, 5.5);
    inspect(move(v1));
}
</pre></blockquote>

<p>
The above program does not treat the moved-from <code>vector</code> as singular.  It
only treats it as a <code>vector</code> with an unknown value.
</p>
<p>
I believe the current proposed wording is consistent with my view on this.
</p>
</blockquote>

<p><i>[
Batavia (2009-05):
]</i></p>

<blockquote><p>
We agree that the proposed resolution
is an improvement over the current wording.
</p></blockquote>

<p><i>[
2009-07 Frankfurt:
]</i></p>


<blockquote><p>
Need to look at again without concepts.
</p></blockquote>

<p><i>[
2009-07 Frankfurt:
]</i></p>


<blockquote><p>
Walter will consult with Dave and Doug.
</p></blockquote>

<p><i>[
2009-10 Santa Cruz:
]</i></p>


<blockquote><p>
We believe this is handled by the resolution to issue <a href="lwg-defects.html#1204" title="Global permission to move (Status: C++11)">1204</a><sup><a href="https://cplusplus.github.io/LWG/issue1204" title="Latest snapshot">(i)</a></sup>,
but there is to much going on in this area to be sure.  Defer for now.
</p></blockquote>

<p><i>[
2010-01-23 Moved to Tentatively NAD Concepts after 5 positive votes on c++std-lib.
Rationale added below.
]</i></p>



<p><b>Rationale:</b></p>
<p>
The current <code>MoveAssignable</code> requirements say everything that can be said
in general.  Each std-defined type has a more detailed specification of move
assignment.
</p>


<p id="res-910"><b>Proposed resolution:</b></p>
<p>
In  [concept.copymove], replace the postcondition in paragraph 7 with:
</p>

<blockquote><p>
<i>Postconditions:</i> <code>*this</code> is equivalent to the value of <code>rv</code> before the
assignment. [<i>Note:</i> there is no requirement on the value of <code>rv</code> after the
assignment, but the
effect should be unsurprising to the user even in case <code>rv</code> is not
immediately destroyed. This may require that resources previously owned
by <code>*this</code> are released instead of transferred to <code>rv</code>. <i>-- end note</i>]
</p></blockquote>





</body>
</html>
