<html>

<head>
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>Moved-from state</title>
<style type="text/css">
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
</style>
</head>

<body>

  <table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="579">
    <tr>
      <td width="153" align="left" valign="top">Document number:</td>
      <td width="426">N3241 = 11-0011</td>
    </tr>
    <tr>
      <td width="153" align="left" valign="top">Date:</td>
      <td width="426">
      <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%Y-%m-%d" startspan -->2011-02-25<!--webbot bot="Timestamp" endspan i-checksum="12106" --></td>
    </tr>
    <tr>
      <td width="153" align="left" valign="top">Project:</td>
      <td width="426">Programming Language C++, Library Working Group</td>
    </tr>
    <tr>
      <td width="153" align="left" valign="top">Reply-to:</td>
      <td width="426">Beman Dawes &lt;bdawes at acm dot org&gt;</td>
    </tr>
  </table>


<h1>CH-18 and US-85: Clarifying the state of <i>moved-from</i> objects </h1>
<h2>Introduction</h2>
<p>FCD comments CH-18 and US-85 request the state of moved-from objects be 
clarified. They are closely related but not identical. This proposal provides 
proposed wording in one place to ensure consistent resolution of both.</p>
<h2>National Body comments</h2>
<h3>CH-18 = 
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3181.html#1353">LWG-1353</a>. [FCD] Clarify the state of a <i>moved-from</i> object</h3>
<p>The general approach on moving is that a library object after moving out is 
in a &quot;valid but unspecified state&quot;. But this is stated at the single object 
specifications, which is error prone (especially if the move operations are 
implicit) and unnecessary duplication. </p>
<p><i>[ Resolution proposed by ballot comment ]</i></p>
<p>Consider putting a general statement to the same effect into clause 17. </p>
<h3>US-85 = 
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3181.html#1374">LWG-1374</a>. [FCD] Clarify <i>moved-from</i> objects are &quot;toxic&quot;</h3>
<p>20.2.1 Table 34 &quot;MoveConstructible requirements&quot; says &quot;Note: rv remains a 
valid object. Its state is unspecified&quot;. Some components give stronger 
guarantees. For example, moved-from <tt>shared_ptr</tt>s are guaranteed <tt>
empty</tt> (20.9.11.2.1/25). In general, what the standard really should say 
(preferably as a global blanket statement) is that moved-from objects can be 
destroyed and can be the destination of an assignment. Anything else is 
radioactive. For example, containers can be &quot;emptier than empty&quot;. This needs to 
be explicit and required generally. </p>
<p>Note: The last time that one of us mentioned &quot;emptier than empty&quot; (i.e. 
containers missing sentinel nodes, etc.) the objection was that containers can 
store sentinel nodes inside themselves in order to avoid dynamically allocating 
them. This is unacceptable because </p>
<p>(a) it forces existing implementations (i.e. Dinkumware's, Microsoft's, 
IBM's, etc.) to change for no good reason (i.e. permitting more operations on 
moved-from objects), and </p>
<p>(b) it invalidates end-iterators when swapping containers. (The Working Paper 
currently permits end-iterator invalidation, which we consider to be wrong, but 
that's a separate argument. In any event, <em>mandating</em> end-iterator 
invalidation is very different from permitting it.) </p>
<p><i>[ Resolution proposed in ballot comment ]</i></p>
<p>State as a general requirement that moved-from objects can be destroyed and 
can be the destination of an assignment. Any other use is undefined behavior.</p>
  <h2>Rationale</h2>
  <p>Howard Hinnant provided the following rationale. The proposed resolution 
  was crafted accordingly.</p>
<blockquote>
  <p>There are two versions of what is required of moved-from objects. &nbsp;One 
  version for std::defined types. &nbsp;One version for user-defined types.</p>
  <p>The version for std::defined types is stricter and represents what I believe 
  is &quot;best practice&quot;. &nbsp;I.e. it is effectively a coding guideline which leads by 
  example. &nbsp;It implicitly tells people the best way to code with respect to move 
  semantics. &nbsp;And we should require just what Beman has written with std::vector 
  as an example.</p>
  <p>The version for user-defined types is weaker. &nbsp;It is the weakest requirements 
  you can reasonably get without breaking std algorithms. &nbsp;std::algorithms 
  generally can't perform anything but a limited set of operations on a 
  user-defined type. &nbsp;These operations are listed in the requirements for each 
  individual algorithm or class. &nbsp;We should require that these operations always 
  work, whether involving a moved-from state or not. &nbsp;We should not require that 
  the user get anything else working in a moved-from state. &nbsp;Except for the 
  container adaptors, we have no algorithms that will call empty() or front() on 
  user-defined types (and in only that case do user-defined types have to have 
  reasonable behavior for those members).</p>
</blockquote>
<h2>Proposed Resolution</h2>
<h3><i>Changes clarifying state of moved-from objects for standard library 
defined types</i></h3>
<p><i>Add a new definition to 17.3 Definitions [definitions]:</i></p>
<blockquote>
  <p>17.3.24 [defns.valid.unspecified]<br>
  <b>valid but unspecified state</b><br>
  an object state that is not specified except that the object's invariants are 
  met and operations on the object behave as specified.</p>
  <p>[<i>Example:</i> If an object <tt>x</tt> of type <tt>std::vector&lt;int&gt;</tt> 
  is in a valid but unspecified state, <tt>x.empty()</tt> can be called 
  unconditionally, and <tt>x.front()</tt> can be called provided <tt>x.empty()</tt> 
  returns <tt>false</tt>. <i>--end example</i>]</p>
</blockquote>
  <p><i>Add a new sub-section, 17.6.4.15 Moved-from state of library types [movedfrom.lib.types]:</i></p>
<blockquote>
  <p>Objects of types defined in the standard library may be moved from 
  ([class.copy]). Move operations may be explicitly specified or  
  implicitly generated. Unless otherwise specified, such moved-from 
  objects shall be placed in a valid but unspecified state ([defns.valid.unspecified]).</p>
</blockquote>
  <p><i>Strike the indicated text from 20.8.14.2.1 function 
  construct/copy/destroy [func.wrap.func.con], 13:</i></p>
<blockquote>
  <p>Effects: Replaces the target of *this with the target of f <del>, leaving f in a 
  valid but unspecified state.</del></p>
</blockquote>
  <p><i>Strike the indicated text from 21.4.2 basic_string constructors and 
  assigment operators [string.cons], 21:</i></p>
<blockquote>
  <p>Effects: If *this and str are not the same object, modifies *this as shown 
  in Table 71. <del>The constructor leaves str in a valid but unspecified state.</del> [ Note: A valid 
  implementation is swap(str).
  end note ]</p>
  <table border="1" cellpadding="8" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111">
    <tr>
      <td><i>21.4.2 basic_string constructors and assigment operators [string.cons] 
      fails to mention the moved-from state for several  other move constructors 
      and move assignments. It is thus an example of why moved-from state should 
      be specified in the clause 17 front matter rather than on a function by 
      function basis. </i></td>
    </tr>
  </table>
</blockquote>
  <p><i>Strike the indicated text from 21.4.6.3 basic_string::assign [string::assign],
  2:</i></p>
<blockquote>
  <p>Effects: The function replaces the string controlled by *this with a string 
  of length str.size() whose
  elements are a copy of the string controlled by str. <del>Leaves str in a valid but 
  unspecified state.</del> [ Note:
  A valid implementation is swap(str). end note ]</p>
</blockquote>
  <p><i>Strike the indicated text from 26.6.2.1 valarray constructors [valarray.cons],
  6:</i></p>
<blockquote>
  <p>The array created by this constructor has the same length as the argument 
  array. The elements are
  initialized with the values of the corresponding elements of the argument 
  array. <del>After construction, v
  is in a valid but unspecified state.</del></p>
</blockquote>
  <p><i>Strike the indicated text from 26.6.2.2 valarray assignment [valarray.assign],
  3:</i></p>
<blockquote>
  <p>Effects: *this obtains the value of v. <del>After the assignment, v is in a 
  valid but unspecified state.</del> If
  the length of v is not equal to the length of *this, resizes *this to make the 
  two arrays the same
  length, as if by calling resize(v.size()), before performing the assignment.</p>
</blockquote>
  <p><i>Strike the indicated text from 28.10.1 match_results constructors [re.results.const],
  5:</i></p>
<blockquote>
  <p>Effects: Move-constructs an object of class match_results from m satisfying 
  the same postconditions
  as Table 141. Additionally, the stored Allocator value is move constructed 
  from m.get_allocator().
  <del>After the initialization of *this, sets m to an unspecified but valid state.</del></p>
</blockquote>
  <p><i>Strike the indicated text from 28.10.1 match_results constructors [re.results.const],
  8:</i></p>
<blockquote>
  <p>Effects: Move-assigns m to *this. The postconditions of this function are 
  indicated in Table 141. <del>After
  the assignment, m is in a valid but unspecified state.</del></p>
</blockquote>
<h3><i>Changes clarifying state of moved-from objects for user-defined types</i></h3>
<p><i>Change Table 34 - MoveConstructible requirements [moveconstructible] as 
indicated:</i></p>
<blockquote>
  <p><del>[ <i>Note:</i></del> <code>rv</code> remains a valid object. Its state is 
  unspecified. <ins> [<i>Note:</i> The object must still meet all applicable 
  requirements. The operations listed in 
  those requirements must work as specified whether  the object is moved-from or not.</ins> 
  <i>-- end note</i> ]</p>
</blockquote>
<p><i>Change Table 36 - MoveAssignable requirements [moveassignable] as 
indicated:</i></p>
<blockquote>
  <p><del>[ <i>Note:</i></del> <code>rv</code> remains a valid object. Its state is 
  unspecified. <ins> [<i>Note:</i> The object must still meet all applicable 
  requirements. The operations listed in 
  those requirements must work as specified whether  the object is moved-from or not.</ins> 
  <i>-- end note</i> ]</p>
</blockquote>
  <h2>Acknowledgements</h2>
  <p>Alisdair Meredith, Daniel Krgler, and Howard Hinnant were instrumental in 
  preparing this paper. Many thanks!</p>
<hr>
  <p>&nbsp;</p>

</body>

</html>