Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are the compiler errors inconsistent in gcc and clang when casting an xvalue to a non-const lvalue reference? [duplicate]

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.

like image 801
SnakePin Avatar asked Nov 18 '20 11:11

SnakePin


1 Answers

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 expression v to type T. If T is an lvalue reference type or an rvalue reference to function type, the result is an lvalue; [...] Conversions that can be performed explicitly using reinterpret_­cast are listed below. No other conversion can be performed explicitly using reinterpret_­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)

  • Can reinterpret_cast (or any cast) convert xvalues to lvalues?

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.

like image 168
dfrib Avatar answered Oct 18 '22 22:10

dfrib