<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 1204: Global permission to move</title>
<meta property="og:title" content="Issue 1204: Global permission to move">
<meta property="og:description" content="C++ library issue. Status: C++11">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue1204.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++11">C++11</a> status.</em></p>
<h3 id="1204"><a href="lwg-defects.html#1204">1204</a>. Global permission to move</h3>
<p><b>Section:</b> 16.4.5.9 <a href="https://wg21.link/res.on.arguments">[res.on.arguments]</a> <b>Status:</b> <a href="lwg-active.html#C++11">C++11</a>
 <b>Submitter:</b> Howard Hinnant <b>Opened:</b> 2009-09-12 <b>Last modified:</b> 2016-01-28</p>
<p><b>Priority: </b>Not Prioritized
</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++11">C++11</a> status.</p>
<p><b>Discussion:</b></p>
<p>
When a library function binds an rvalue reference parameter to an argument, the
library must be able to assume that the bound argument is a temporary, and not
a moved-from lvalue.  The reason for this is that the library function must be
able to modify that argument without concern that such modifications will corrupt
the logic of the calling code.  For example:
</p>

<blockquote><pre>
template &lt;class T, class A&gt;
void
vector&lt;T, A&gt;::push_back(value_type&amp;&amp; v)
{
    <span style="color:#C80000">// This function should move from v, potentially modifying</span>
    <span style="color:#C80000">// the object v is bound to.</span>
}
</pre></blockquote>

<p>
If <code>v</code> is truly bound to a temporary, then <code>push_back</code> has the
<em>only</em> reference to this temporary in the entire program.  Thus any
modifications will be invisible to the rest of the program.
</p>

<p>
If the client supplies <code>std::move(x)</code> to <code>push_back</code>, the onus is
on the client to ensure that the value of <code>x</code> is no longer important to
the logic of his program after this statement.  I.e. the client is making a statement
that <code>push_back</code> may treat <code>x</code> as a temporary.
</p>

<blockquote><p><em>
The above statement is the very foundation upon which move semantics is based.
</em></p></blockquote>

<p>
The standard is currently lacking a global statement to this effect.  I propose
the following addition to 16.4.5.9 <a href="https://wg21.link/res.on.arguments">[res.on.arguments]</a>:
</p>

<blockquote>
<p>
Each of the following statements applies to all arguments to functions
defined in the C++ standard library, unless explicitly stated otherwise.
</p>
<ul>
<li>
If an argument to a function has an invalid value (such as a value
outside the domain of the function, or a pointer invalid for its
intended use), the behavior is undefined.
</li>
<li>
If a function argument is described as being an array, the pointer
actually passed to the function shall have a value such that all address
computations and accesses to objects (that would be valid if the pointer
did point to the first element of such an array) are in fact valid.
</li>
<li><ins>
If a function argument binds to an rvalue reference parameter, the C++
standard library may assume that this parameter is a unique reference
to this argument.  If the parameter is a generic parameter of the
form <code>T&amp;&amp;</code>, and an lvalue of type <code>A</code> is bound,
then the binding is considered to be to an lvalue reference
(13.10.3.2 <a href="https://wg21.link/temp.deduct.call">[temp.deduct.call]</a>) and thus not covered by this clause.
[<i>Note:</i>
If a program casts an lvalue to an rvalue while passing that lvalue to
a library function (e.g. <code>move(x)</code>), then the program is effectively
asking the library to treat that lvalue as a temporary.  The library is at
liberty to optimize away aliasing checks which might be needed if the argument
were an lvalue.
&mdash; <i>end note</i>]
</ins></li>
</ul>

</blockquote>

<p>
Such a global statement will eliminate the need for piecemeal statements such as
23.2.2 <a href="https://wg21.link/container.requirements.general">[container.requirements.general]</a>&#47;13:
</p>

<blockquote><p>
An object bound to an rvalue reference parameter of a member function of
a container shall not be an element of that container; no diagnostic
required.
</p></blockquote>

<p>
Additionally this clarifies that move assignment operators need not perform the
traditional <code>if (this != &amp;rhs)</code> test commonly found (and needed) in
copy assignment operators.
</p>

<p><i>[
2009-09-13 Niels adds:
]</i></p>


<blockquote><p>
Note: This resolution supports the change of 31.10.3.3 <a href="https://wg21.link/filebuf.assign">[filebuf.assign]</a>&#47;1,
proposed by LWG <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>.
</p></blockquote>

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


<blockquote><p>
Move to Ready.
</p></blockquote>



<p id="res-1204"><b>Proposed resolution:</b></p>
<p>
Add a bullet to 16.4.5.9 <a href="https://wg21.link/res.on.arguments">[res.on.arguments]</a>:
</p>

<blockquote>
<p>
Each of the following statements applies to all arguments to functions
defined in the C++ standard library, unless explicitly stated otherwise.
</p>
<ul>
<li>
If an argument to a function has an invalid value (such as a value
outside the domain of the function, or a pointer invalid for its
intended use), the behavior is undefined.
</li>
<li>
If a function argument is described as being an array, the pointer
actually passed to the function shall have a value such that all address
computations and accesses to objects (that would be valid if the pointer
did point to the first element of such an array) are in fact valid.
</li>
<li><ins>
If a function argument binds to an rvalue reference parameter, the C++
standard library may assume that this parameter is a unique reference
to this argument.  If the parameter is a generic parameter of the
form <code>T&amp;&amp;</code>, and an lvalue of type <code>A</code> is bound,
then the binding is considered to be to an lvalue reference
(13.10.3.2 <a href="https://wg21.link/temp.deduct.call">[temp.deduct.call]</a>) and thus not covered by this clause.
[<i>Note:</i>
If a program casts an lvalue to an rvalue while passing that lvalue to
a library function (e.g. <code>move(x)</code>), then the program is effectively
asking the library to treat that lvalue as a temporary.  The library is at
liberty to optimize away aliasing checks which might be needed if the argument
were an lvalue.
&mdash; <i>end note</i>]
</ins></li>
</ul>
</blockquote>

<p>
Delete 23.2.2 <a href="https://wg21.link/container.requirements.general">[container.requirements.general]</a>&#47;13:
</p>

<blockquote><p><del>
An object bound to an rvalue reference parameter of a member function of
a container shall not be an element of that container; no diagnostic
required.
</del></p></blockquote>






</body>
</html>
