<HTML>
<HEAD>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<TITLE>
    CWG Issue 2310</TITLE>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<STYLE TYPE="text/css">
  INS { text-decoration:none; font-weight:bold; background-color:#A0FFA0 }
  .INS { text-decoration:none; background-color:#D0FFD0 }
  DEL { text-decoration:line-through; background-color:#FFA0A0 }
  .DEL { text-decoration:line-through; background-color: #FFD0D0 }
  @media (prefers-color-scheme: dark) {
    HTML { background-color:#202020; color:#f0f0f0; }
    A { color:#5bc0ff; }
    A:visited { color:#c6a8ff; }
    A:hover, a:focus { color:#afd7ff; }
    INS { background-color:#033a16; color:#aff5b4; }
    .INS { background-color: #033a16; }
    DEL { background-color:#67060c; color:#ffdcd7; }
    .DEL { background-color:#67060c; }
  }
  SPAN.cmnt { font-family:Times; font-style:italic }
</STYLE>
</HEAD>
<BODY>
<P><EM>This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21
  Core Issues List revision 118b.
  See http://www.open-std.org/jtc1/sc22/wg21/ for the official
  list.</EM></P>
<P>2025-09-28</P>
<HR>
<A NAME="2310"></A><H4>2310.
  
Type completeness and derived-to-base pointer conversions
</H4>
<B>Section: </B>7.3.12&#160; [<A href="https://wg21.link/conv.ptr">conv.ptr</A>]
 &#160;&#160;&#160;

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

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

 <B>Date: </B>2016-08-08<BR>


<P>[Accepted as a DR at the February, 2019 meeting.]</P>



<P>The specification of derived-to-base pointer conversions in
7.3.12 [<A href="https://wg21.link/conv.ptr#3">conv.ptr</A>] paragraph 3 does not require that the derived
class be complete at the point of the conversion. This leaves unclear the
status of an example like the following, on which there is implementation
divergence:</P>

<PRE>
  template&lt;typename A, typename B&gt; struct check_derived_from {
    static A a;
    static constexpr B *p = &amp;a;
  };
  struct W {};
  struct X {};
  struct Y {};
  struct Z : W,
    X, check_derived_from&lt;Z, X&gt;,  //<SPAN CLASS="cmnt"> #1 </SPAN>
    check_derived_from&lt;Z, Y&gt;, Y { //<SPAN CLASS="cmnt"> #2 </SPAN>
    check_derived_from&lt;Z, W&gt; cdf; //<SPAN CLASS="cmnt"> #3 </SPAN>
  };
</PRE>

<P><B>Notes from the March, 2018 meeting:</B></P>

<P>The consensus of CWG was that the derived class must be complete at
the point of the conversion, and thus all three attempted conversions in
the example are ill-formed.</P>

<P><B>Proposed resolution (November, 2018):</B></P>

<OL>
<LI><P>Change 7.3.12 [<A href="https://wg21.link/conv.ptr#3">conv.ptr</A>] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

A prvalue of type &#8220;pointer to <I>cv</I>
<TT>D</TT>&#8221;, where <TT>D</TT> is a <INS>complete</INS>
class type, can be converted to a prvalue of type
&#8220;pointer to <I>cv</I>
<TT>B</TT>&#8221;, where <TT>B</TT> is a base class
(11.7 [<A href="https://wg21.link/class.derived">class.derived</A>]) of <TT>D</TT>. If <TT>B</TT> is
an inaccessible...

</BLOCKQUOTE>

<LI><P>Change 7.3.13 [<A href="https://wg21.link/conv.mem#2">conv.mem</A>] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

A prvalue of type &#8220;pointer to member of <TT>B</TT> of
type <I>cv</I> <TT>T</TT>&#8221;, where B<TT></TT> is a
class type, can be converted to a prvalue of type
&#8220;pointer to member of <TT>D</TT> of type <I>cv</I>
<TT>T</TT>&#8221;, where <TT>D</TT>
is a <INS>complete class</INS>
derived <DEL>class</DEL>
(11.7 [<A href="https://wg21.link/class.derived">class.derived</A>]) <DEL>of</DEL> <INS>from</INS>
<TT>B</TT>. If <TT>B</TT>
is an inaccessible...

</BLOCKQUOTE>

<LI><P>Change 7.6.1.9 [<A href="https://wg21.link/expr.static.cast">expr.static.cast</A>] paragraphs 11 and 12 as
followed:</P></LI>

<BLOCKQUOTE>

<P>A prvalue of type &#8220;pointer to <I>cv1</I>
<TT>B</TT>&#8221;, where <TT>B</TT>
is a <INS>complete</INS>
class type, can be converted to a prvalue of type
&#8220;pointer to <I>cv2</I>
<TT>D</TT>&#8221;, where D is a class derived
(11.7 [<A href="https://wg21.link/class.derived">class.derived</A>]) from B , if cv2 is the same...</P>

<P>A prvalue of type &#8220;pointer to member of <TT>D</TT>
of type <I>cv1</I>
<TT>T</TT>&#8221; can be converted to a prvalue of type
&#8220;pointer to member of <TT>B</TT>
of type <I>cv2</I>
<TT>T</TT>&#8221;, where <TT>B</TT>
is a base class (11.7 [<A href="https://wg21.link/class.derived">class.derived</A>]) of <INS>a complete class</INS>
<TT>D</TT>, if <I>cv2</I>
is the same...</P>

</BLOCKQUOTE>

</OL>

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