This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115e. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-11-11


2939. Do not allow reinterpret_cast from prvalue to rvalue reference

Section: 7.6.1.10  [expr.reinterpret.cast]     Status: tentatively ready     Submitter: Brian Bi     Date: 2024-10-01

(From submission #617.)

In 7.6.1.10 [expr.reinterpret.cast] paragraph 11, there is an issue similar to the one described in issue 2879: The operand for a cast to reference type can be a "glvalue of type T1", which implies that a prvalue is also acceptable, because it is materialized per 7.2.1 [basic.lval] paragraph 7. However, no implementation accepts reinterpret_cast<double&&>(0).

Suggested resolution [SUPERSEDED]:

  1. Change in 7.6.1.10 [expr.reinterpret.cast] paragraph 1 as follows:

    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; if T is an rvalue reference to object type, the result is an xvalue; otherwise, the result is a prvalue and the lvalue-to-rvalue (7.3.2 [conv.lval]), array-to-pointer (7.3.3 [conv.array]), and function-to-pointer (7.3.4 [conv.func]) standard conversions are performed on the expression v. The temporary materialization conversion (7.3.5 [conv.rval]) is not performed on v. Conversions that can be performed explicitly using reinterpret_cast are listed below. No other conversion can be performed explicitly using reinterpret_cast.
  2. Remove 7.6.1.10 [expr.reinterpret.cast] paragraph 3:

    [Note 1: The mapping performed by reinterpret_cast might, or might not, produce a representation different from the original value. —end note]
  3. Remove from 7.6.1.10 [expr.reinterpret.cast] paragraph 6 as follows:

    ... [Note 5: See also 7.3.12 [conv.ptr] for more details of pointer conversions. —end note]
  4. Change in 7.6.1.10 [expr.reinterpret.cast] paragraph 11 as follows:

    A glvalue of type T1, designating an object or function x, can be cast to the type “reference to T2” if an expression of type “pointer to T1” can be explicitly converted to the type “pointer to T2” using a reinterpret_cast. The result is that of *reinterpret_cast<T2 *>(p) where p is a pointer to x of type “pointer to T1”. [ Note: No temporary is created, no copy is made, and no constructors (11.4.5 [class.ctor]) or conversion functions (11.4.8 [class.conv]) are called [ Footnote: ... ]. -- end note ]

CWG 2024-10-11

The note in 7.6.1.10 [expr.reinterpret.cast] paragraph 3 should be kept, and the list of exceptions in 7.2.1 [basic.lval] paragraph 7 established by issue 2879 should be amended with a cross-reference to 7.6.1.10 [expr.reinterpret.cast].

Proposed resolution (approved by CWG 2024-10-25):

  1. Change in 7.2.1 [basic.lval] paragraph 7 as follows:

    Unless otherwise specified (7.6.1.10 [expr.reinterpret.cast], 7.6.1.11 [expr.const.cast]), whenever a prvalue appears as an operand of an operator that expects a glvalue for that operand, the temporary materialization conversion (7.3.5 [conv.rval]) is applied to convert the expression to an xvalue.
  2. Remove from 7.6.1.10 [expr.reinterpret.cast] paragraph 6 as follows:

    ... [Note 5: See also 7.3.12 [conv.ptr] for more details of pointer conversions. —end note]
  3. Change in 7.6.1.10 [expr.reinterpret.cast] paragraph 11 as follows:

    A glvalue of type T1, designating an object or function x, can be cast to the type “reference to T2” if an expression of type “pointer to T1” can be explicitly converted to the type “pointer to T2” using a reinterpret_cast. The temporary materialization conversion (7.3.5 [conv.rval]) is not performed on v. The result is that of *reinterpret_cast<T2 *>(p) where p is a pointer to x of type “pointer to T1”. [ Note: No temporary is created, no copy is made, and no constructors (11.4.5 [class.ctor]) or conversion functions (11.4.8 [class.conv]) are called [ Footnote: ... ]. -- end note ]