Title
Reference reinterpret_cast and pointer-interconvertibility
Status
cd5
Section
7.6.1.10 [expr.reinterpret.cast]
Submitter
Richard Smith

Created on 2017-04-07.00:00:00 last changed 2 months ago

Messages

Date: 2017-07-15.00:00:00

Proposed resolution (July, 2017):

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

A glvalue expression of type T1, designating an object 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 refers to the same object as the source glvalue, but with the specified type is that of *reinterpret_cast<T2 *>(p) where p is a pointer to x of type “pointer to T1. [Note: That is, for lvalues, a reference cast reinterpret_cast<T&>(x) has the same effect as the conversion *reinterpret_cast<T*>(&x) with the built-in & and * operators (and similarly for reinterpret_cast<T&&>(x)). —end note] No temporary is created, no copy is made, and constructors (11.4.5 [class.ctor]) or conversion functions (11.4.8 [class.conv]) are not called. [Footnote: This is sometimes referred to as a type pun when the result refers to the same object as the source glvalue. —end footnote]
Date: 2017-11-15.00:00:00

[Accepted as a DR at the November, 2017 meeting.]

The changes from document P0137 make it clear that this is valid:

  struct A { int n; } a; 
  int *p = reinterpret_cast<int*>(&a); // ok, a and a.n are pointer-interconvertible
  int m = *p;                          // ok, p points to a.n

but the handling for that case does not extend to this one:

  int &r = reinterpret_cast<int&>(a); 
  int n = r; 

The relevant rule is 7.6.1.10 [expr.reinterpret.cast] paragraph 11:

A glvalue expression of type T1 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 refers to the same object as the source glvalue, but with the specified type. [Note: That is, for lvalues, a reference cast reinterpret_cast<T&>(x) has the same effect as the conversion *reinterpret_cast<T*>(&x) with the built-in & and * operators (and similarly for reinterpret_cast<T&&>(x)). —end note]

Note that the normative rule and the note specify different rules: under the rule described in the note, the result would be a reference to the object a.n. According to the normative rule, however, we get a reference to the object a with type n.

History
Date User Action Args
2020-12-15 00:00:00adminsetstatus: dr -> cd5
2018-02-27 00:00:00adminsetmessages: + msg6113
2017-04-07 00:00:00admincreate