Title
Global permission to move
Status
c++11
Section
[res.on.arguments]
Submitter
Howard Hinnant

Created on 2009-09-12.00:00:00 last changed 154 months ago

Messages

Date: 2010-10-21.18:28:33

Proposed resolution:

Add a bullet to [res.on.arguments]:

Each of the following statements applies to all arguments to functions defined in the C++ standard library, unless explicitly stated otherwise.

  • 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.
  • 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.
  • 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 T&&, and an lvalue of type A is bound, then the binding is considered to be to an lvalue reference ([temp.deduct.call]) and thus not covered by this clause. [Note: If a program casts an lvalue to an rvalue while passing that lvalue to a library function (e.g. move(x)), 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. — end note]

Delete [container.requirements.general]/13:

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.

Date: 2010-10-21.18:28:33

[ 2009 Santa Cruz: ]

Move to Ready.

Date: 2009-09-13.00:00:00

[ 2009-09-13 Niels adds: ]

Note: This resolution supports the change of [filebuf.assign]/1, proposed by LWG 900.

Date: 2009-09-12.00:00:00

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:

template <class T, class A>
void
vector<T, A>::push_back(value_type&& v)
{
    // This function should move from v, potentially modifying
    // the object v is bound to.
}

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

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

The above statement is the very foundation upon which move semantics is based.

The standard is currently lacking a global statement to this effect. I propose the following addition to [res.on.arguments]:

Each of the following statements applies to all arguments to functions defined in the C++ standard library, unless explicitly stated otherwise.

  • 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.
  • 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.
  • 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 T&&, and an lvalue of type A is bound, then the binding is considered to be to an lvalue reference ([temp.deduct.call]) and thus not covered by this clause. [Note: If a program casts an lvalue to an rvalue while passing that lvalue to a library function (e.g. move(x)), 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. — end note]

Such a global statement will eliminate the need for piecemeal statements such as [container.requirements.general]/13:

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.

Additionally this clarifies that move assignment operators need not perform the traditional if (this != &rhs) test commonly found (and needed) in copy assignment operators.

History
Date User Action Args
2011-08-23 20:07:26adminsetstatus: wp -> c++11
2010-10-21 18:28:33adminsetmessages: + msg1140
2010-10-21 18:28:33adminsetmessages: + msg1139
2010-10-21 18:28:33adminsetmessages: + msg1138
2009-09-12 00:00:00admincreate