Is the following code legal (by C++11 and/or C++14 standard(s))?
#include
#include
using namespace std;
void foo(int &
Update: The code is ill-formed in C++11. Answer below is for C++14. See note at the end of this answer.
I believe this code is both well-formed and well-defined. Here's why.
The result of std::move is an xvalue [1], which is a type of glvalue; and converting a glvalue to an lvalue reference with reinterpret_cast appears to be allowed by the wording of the standard:
A glvalue expression of type
T1can be cast to the type “reference toT2” if an expression of type “pointer toT1” can be explicitly converted to the type “pointer toT2” using areinterpret_cast. The result refers to the same object as the source glvalue, but with the specified type. [ Note: That is, for lvalues, a reference castreinterpret_casthas the same effect as the conversion(x) *reinterpret_castwith the built-in(&x) &and*operators (and similarly forreinterpret_cast). — end note ] No temporary is created, no copy is made, and constructors (12.1) or conversion functions (12.3) are not called.73(x)
Since "pointer to int" can be converted to "pointer to int", this reinterpret_cast is also allowed. The standard doesn't say anything about whether the destination type has to be an lvalue reference or rvalue reference.
The result of the cast is well-defined by the paragraph above: it refers to the same object as the source glvalue---that is, a temporary int object with the value 5. ([dcl.init.ref] specifies that a temporary is created when a prvalue is bound to a reference.)
Accessing the value through the int& also doesn't violate any aliasing rules since the original object was also of type int. In fact I believe it would even be well-defined to modify the temporary through the lvalue thus obtained.
Note: The C++11 wording says "lvalue expression", not "glvalue expression". The wording with "glvalue expression" is from N3936, which is the final working draft for C++14. I'm not an expert in how the standardization process works, but I believe this means that the change of "lvalue" to "glvalue" was already voted in by the committee, and when ISO publishes the C++14 standard, it's going to be pretty similar to what it says above.
[1] Except in the rare case in which the argument is a function; in that case the result is an lvalue, since there are no function rvalues.