Can someone explain why both compilers throw an error on the second example whereas only gcc throws an error on the first example? Is it somehow related to the result of the static_cast
being an xvalue?
int& example1 = reinterpret_cast<int&>(static_cast<int&&>(10));
//(gcc 10.2) error: invalid cast of an rvalue expression of type 'int' to type 'int&'
//(clang 11.0.0) no errors
int& example2 = reinterpret_cast<int&>(10);
//(gcc 10.2) error: invalid cast of an rvalue expression of type 'int' to type 'int&'
//(clang 11.0.0) error: reinterpret_cast from rvalue to reference type 'int &'
Also I'm not sure but I think the first example is well-formed because according to the standard, an xvalue is a type of a glvalue, right? And this [expr.reinterpret.cast]/11 part of the standard says that I should be able to cast T1 glvalues to the type “reference to T2” with the T1 being the same type as T2 in this case.
reinterpret_cast<int&>(10);
This program is ill-formed, as the expression being converted from is a prvalue. From [expr.reinterpret.cast]/1:
The result of the expression
reinterpret_cast<T>(v)
is the result of converting the expressionv
to typeT
. IfT
is an lvalue reference type or an rvalue reference to function type, the result is an lvalue; [...] Conversions that can be performed explicitly usingreinterpret_cast
are listed below. No other conversion can be performed explicitly usingreinterpret_cast
.
None of the clauses that follows allows a reinterpret_cast
from a (p)rvalue that is not a pointer.
#include <memory>
reinterpret_cast<int&>(std::move(10));
Here, the expression being converted from is an xvalue, and as shown in the Q&A linked to in a comment by @LanguageLawyer (which is arguably a dupe target for this Q&A)
this is well-formed, as of C++14 (updated as a DR fix also to C++11) and the actual implementation of CWG 1268:
1268. reinterpret_cast of an xvalue operand Section: 8.2.10 [expr.reinterpret.cast]
Status: CD3
Submitter: Michael Wong
Date: 2011-03-21
[Moved to DR at the October, 2012 meeting.]
8.2.10 [expr.reinterpret.cast] paragraph 11, dealing with casting to reference types, only allows an lvalue operand. Presumably it should allow a glvalue operand when the target is an rvalue reference type.
[...]
Note that the emphasized segment proposes to allow this only when the target is an rvalue reference, but the actually updated [expr.reinterpret.cast]/11 removed this restriction.
Consequently, GCC is wrong to reject the first example.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With