Title
Cv-qualification of temporary to which a reference is bound
Status
cd6
Section
9.4.4 [dcl.init.ref]
Submitter
Jiang An

Created on 2021-03-20.00:00:00 last changed 20 months ago

Messages

Date: 2021-11-15.00:00:00

Proposed resolution, May, 2021:

Change 9.4.4 [dcl.init.ref] bullet 5.4.2 as follows:

A reference to type “cv1 T1” is initialized by an expression of type “cv2 T2” as follows:

  • ...

  • Otherwise:

    • If T1 or T2 is a class type and T1 is not reference-related to T2...

    • Otherwise, the initializer expression is implicitly converted to a prvalue of type cv1 T1. The temporary materialization conversion is applied, considering the type of the prvalue to be “cv1 T1”, and the reference is bound to the result.

Date: 2021-06-15.00:00:00

[Accepted as a DR at the June, 2021 meeting.]

According to 9.4.4 [dcl.init.ref] bullet 5.4.2, when a reference is initialized with a non-class value and the referenced type is not reference-related to the type of the initializer,

  • Otherwise, the initializer expression is implicitly converted to a prvalue of type “cv1 T1”. The temporary materialization conversion is applied and the reference is bound to the result.

According to 7.2.2 [expr.type] paragraph 2, the cv-qualification is discarded before invoking the temporary materialization conversion:

If a prvalue initially has the type “cv T”, where T is a cv-unqualified non-class, non-array type, the type of the expression is adjusted to T prior to any further analysis.

This results in a reference-to-const being bound to a non-const object, meaning that a const_cast of the reference to a reference-to-nonconst would allow a well-defined modification of the value:

  constexpr const int &r = 42;
  const_cast<int &>(r) = 23;  // Well-defined
  static_assert(r == 42);     // Ill-formed, non-constant expression

This was different from the situation before the advent of the temporary materialization conversion in C++17, when the description of the reference binding created the temporary explicitly with the cv-qualified type:

If T1 is a non-class type, a temporary of type “cv1 T1” is created and copy-initialized (8.5) from the initializer expression. The reference is then bound to the temporary.

Presumably this difference was unintentional and should be reverted.

History
Date User Action Args
2022-08-19 07:54:33adminsetstatus: drwp -> cd6
2021-11-15 00:00:00adminsetmessages: + msg6592
2021-03-20 00:00:00admincreate