<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=us-ascii">
<TITLE>
    Core "ready" Issues
   </TITLE>
</HEAD>
<BODY>
<TABLE ALIGN="RIGHT" CELLSPACING="0" CELLPADDING="0">
<TR>
<TD ALIGN="RIGHT">
      Document number:
     </TD>
<TD>
       &#160;P0817R0</TD>
</TR>
<TR>
<TD ALIGN="RIGHT">
      Date:
     </TD>
<TD>
      &#160;2017-10-16</TD>
</TR>
<TR>
<TD ALIGN="RIGHT">
      Project:
     </TD>
<TD>
      &#160;Programming Language C++
     </TD>
</TR>
<TR>
<TD ALIGN="RIGHT">
      Reference:
     </TD>
<TD>
      &#160;ISO/IEC IS 14882:2014
     </TD>
</TR>
<TR>
<TD ALIGN="RIGHT">
      Reply to:
     </TD>
<TD>
      &#160;William M. Miller
     </TD>
</TR>
<TR>
<TD></TD>
<TD>
      &#160;Edison Design Group, Inc.
     </TD>
</TR>
<TR>
<TD></TD>
<TD>
      &#160;<A HREF="mailto://wmm@edg.com">wmm@edg.com</A></TD>
</TR>
</TABLE><BR CLEAR="ALL"><BR><CENTER>
<H2>
     Core Language Working Group "ready" Issues
     for the
     November, 2017 (Albuquerque) meeting
    </H2>
</CENTER><BR><P>
    Section references in this document reflect the section numbering
    of document
    <A HREF="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf">WG21 N4659</A>.
   </P>
<HR><A NAME="2342"></A><H4>2342.
  
Reference <TT>reinterpret_cast</TT> and pointer-interconvertibility
</H4><B>Section: </B>8.2.10&#160; [expr.reinterpret.cast]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>2017-04-07




<P>The changes from document P0137 make it clear that this is valid:</P>

<PRE>
  struct A { int n; } a; 
  int *p = reinterpret_cast&lt;int*&gt;(&amp;a); //<SPAN style="font-family:Times;font-style:italic"> ok, </SPAN>a<SPAN style="font-family:Times;font-style:italic"> and </SPAN>a.n<SPAN style="font-family:Times;font-style:italic"> are pointer-interconvertible</SPAN>
  int m = *p;                          //<SPAN style="font-family:Times;font-style:italic"> ok, </SPAN>p<SPAN style="font-family:Times;font-style:italic"> points to </SPAN>a.n
</PRE>

<P>but the handling for that case does not extend to this one:</P>

<PRE>
  int &amp;r = reinterpret_cast&lt;int&amp;&gt;(a); 
  int n = r; 
</PRE>

<P>The relevant rule is 8.2.10 [expr.reinterpret.cast] paragraph 11:</P>

<BLOCKQUOTE>

A glvalue expression of type <TT>T1</TT> can be cast to the type
&#8220;reference to <TT>T2</TT>&#8221; if an expression of type
&#8220;pointer to <TT>T1</TT>&#8221; can be explicitly converted to the
type &#8220;pointer to <TT>T2</TT>&#8221; using a
<TT>reinterpret_cast</TT>. The result refers to the same object as the
source glvalue, but with the specified type. [<I>Note:</I> That is, for
lvalues, a reference cast <TT>reinterpret_cast&lt;T&amp;&gt;(x)</TT> has
the same effect as the 
conversion <TT>*reinterpret_cast&lt;T*&gt;(&amp;x)</TT> with the
built-in <TT>&amp;</TT> and <TT>*</TT> operators (and similarly for
<TT>reinterpret_cast&lt;T&amp;&amp;&gt;(x)</TT>). &#8212;<I>end note</I>]

</BLOCKQUOTE>

<P>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 <TT>a.n</TT>. According to the normative
rule, however, we get a reference to the object <TT>a</TT> with type
<TT>n</TT>.</P>

<P><B>Proposed resolution (July, 2017):</B></P>

<P>Change 8.2.10 [expr.reinterpret.cast] paragraph 11 as follows:</P>

<BLOCKQUOTE>

A glvalue expression of type <TT>T1</TT><SPAN style="font-weight:bold;background-color:#A0FFA0">, designating an object
<TT>x</TT>,</SPAN> can be cast to the type &#8220;reference
to <TT>T2</TT>&#8221; if an expression of type &#8220;pointer
to <TT>T1</TT>&#8221; can be explicitly converted to the type
&#8220;pointer to <TT>T2</TT>&#8221; using a
<TT>reinterpret_cast</TT>. The result <SPAN style="text-decoration:line-through;background-color:#FFA0A0">refers to the same object as the
source glvalue, but with the specified type</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">is that of <TT>*reinterpret_cast&lt;T2 *&gt;(p)</TT> where
<TT>p</TT> is a pointer to <I>x</I> of type &#8220;pointer to
<TT>T1</TT>&#8221;</SPAN>. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">[<I>Note:</I> That is, for
lvalues, a reference cast <TT>reinterpret_cast&lt;T&amp;&gt;(x)</TT> has
the same effect as the 
conversion <TT>*reinterpret_cast&lt;T*&gt;(&amp;x)</TT> with the
built-in <TT>&amp;</TT> and <TT>*</TT> operators (and similarly for
<TT>reinterpret_cast&lt;T&amp;&amp;&gt;(x)</TT>). &#8212;<I>end
note</I>]</SPAN> No temporary is created, no copy is made, and constructors
(15.1 [class.ctor]) or conversion functions
(15.3 [class.conv]) are not called. [<I>Footnote:</I> This is
sometimes referred to as a <I>type pun</I> <SPAN style="font-weight:bold;background-color:#A0FFA0">when the result refers to
the same object as the source glvalue</SPAN>. &#8212;<I>end footnote</I>]

</BLOCKQUOTE>

<BR><BR></BODY>
</HTML>
