<HTML>
<HEAD>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<TITLE>
    Core "ready" Issues
   </TITLE>
<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 }
  SPAN.cmnt { font-family:Times; font-style:italic }
</STYLE>
</HEAD>
<BODY>
<TABLE ALIGN="RIGHT" CELLSPACING="0" CELLPADDING="0">
<TR>
<TD ALIGN="RIGHT">
      Document number:
     </TD>
<TD>
       &#160;P3196R0</TD>
</TR>
<TR>
<TD ALIGN="RIGHT">
      Date:
     </TD>
<TD>
      &#160;2024-03-22</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:2020
     </TD>
</TR>
<TR>
<TD ALIGN="RIGHT">
      Reply to:
     </TD>
<TD>
      &#160;Jens Maurer
     </TD>
</TR>
<TR>
<TD></TD>
<TD>
      &#160;<A HREF="mailto://jens.maurer@gmx.net">jens.maurer@gmx.net</A>
</TD>
</TR>
</TABLE>
<BR CLEAR="ALL"><BR><CENTER><H2>
     Core Language Working Group "ready" Issues
     for the
     March, 2024 meeting
    </H2></CENTER>
<BR><P>
    References in this document reflect the section and paragraph
    numbering of document
    <A HREF="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4971.pdf">WG21 N4971</A>.
   </P>
<HR>
<A NAME="453"></A><H4>453.
  
References may only bind to &#8220;valid&#8221; objects
</H4>
<B>Section: </B>9.3.4.3&#160; [<A href="https://wg21.link/dcl.ref">dcl.ref</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Gennaro Prota
 &#160;&#160;&#160;

 <B>Date: </B>18 Jan 2004


<P>9.3.4.3 [<A href="https://wg21.link/dcl.ref#4">dcl.ref</A>] paragraph 4 says:</P>
<BLOCKQUOTE>
  A reference shall be initialized to refer to a valid object or
  function. [Note: in particular, a null reference cannot exist
  in a well-defined program, because the only way to create such
  a reference would be to bind it to the "object" obtained by
  dereferencing a null pointer, which causes undefined behavior
  ...]
</BLOCKQUOTE>
<P>What is a "valid" object? In particular the expression "valid object"
seems to exclude uninitialized objects, but the response to Core Issue
363 clearly says that's not the intent. This is an example
(overloading construction on constness of *this) by John Potter, which
I think is supposed to be legal C++ though it binds references to
objects that are not initialized yet:</P>
<PRE>
 struct Fun {
    int x, y;
    Fun (int x, Fun const&amp;) : x(x), y(42) { }
    Fun (int x, Fun&amp;) : x(x), y(0) { }
  };
  int main () {
    const Fun f1 (13, f1);
    Fun f2 (13, f2);
    cout &lt;&lt; f1.y &lt;&lt; " " &lt;&lt; f2.y &lt;&lt; "\n";
  }
</PRE>

<P>Suggested resolution: Changing the final part of
9.3.4.3 [<A href="https://wg21.link/dcl.ref#4">dcl.ref</A>] paragraph 4 to:</P>
<BLOCKQUOTE>
  A reference shall be initialized to refer to an object or function.
  From its point of declaration on (see 6.4.2 [<A href="https://wg21.link/basic.scope.pdecl">basic.scope.pdecl</A>])
  its name is an lvalue
  which refers to that object or function. The reference may be
  initialized to refer to an uninitialized object but, in that case,
  it is usable in limited ways (6.7.3 [<A href="https://wg21.link/basic.life">basic.life</A>], paragraph 6)
  [Note: On the other hand, a declaration like this:
<PRE>
    int &amp; ref = *(int*)0;
</PRE>
  is ill-formed because ref will not refer to any object or function
  ]
</BLOCKQUOTE>

<P>I also think a "No diagnostic is required." would better be added
(what about something like int&amp; r = r; ?)</P>

<P><B>Proposed Resolution (October, 2004) [SUPERSEDED]:</B></P>

<P>(Note: the following wording depends on the proposed
resolution for issue 232.)</P>

<P>Change 9.3.4.3 [<A href="https://wg21.link/dcl.ref#4">dcl.ref</A>] paragraph 4 as follows:</P>
<BLOCKQUOTE>

<P>
<DEL>A reference shall be initialized to refer to a valid object
or function.</DEL> <INS>If an lvalue to which a reference is directly
bound designates neither an existing object or function of an
appropriate type (9.4.4 [<A href="https://wg21.link/dcl.init.ref">dcl.init.ref</A>]), nor a region of
memory of suitable size and alignment to contain an object of the
reference's type (6.7.2 [<A href="https://wg21.link/intro.object">intro.object</A>], 6.7.3 [<A href="https://wg21.link/basic.life">basic.life</A>], 6.8 [<A href="https://wg21.link/basic.types">basic.types</A>]), the behavior is
undefined.</INS> [<I>Note:</I> in particular, a null reference cannot
exist in a well-defined program, because the only way to create
such a reference would be to bind it to the
<DEL>&#8220;object&#8221;</DEL> <INS>empty lvalue</INS> obtained by
dereferencing a null pointer, which <DEL>causes undefined behavior.
As</DEL> <INS>does not designate an object or function.  Also, as
</INS> described in 11.4.10 [<A href="https://wg21.link/class.bit">class.bit</A>],
a reference cannot be bound directly to a
bit-field. ]</P>

<P><INS>The name of a reference shall not be used in its own
initializer.  Any other use of a reference before it is
initialized results in undefined behavior.  [<I>Example:</I>
</INS></P>

<INS>
<PRE>
  int&amp; f(int&amp;);
  int&amp; g();

  extern int&amp; ir3;
  int* ip = 0;

  int&amp; ir1 = *ip;     // <I>undefined behavior: null pointer</I>
  int&amp; ir2 = f(ir3);  // <I>undefined behavior: </I>ir3<I> not yet initialized</I>
  int&amp; ir3 = g();
  int&amp; ir4 = f(ir4);  // <I>ill-formed: </I>ir4<I> used in its own initializer</I>
</PRE>
&#8212;<I>end example</I>]
</INS>
</BLOCKQUOTE>

<P>
<B>Rationale: </B> The proposed wording goes beyond the specific
concerns of the issue.  It was noted that, while the current
wording makes cases like <TT>int&amp; r = r;</TT> ill-formed (because
<TT>r</TT> in the initializer does not "refer to a valid object"), an
inappropriate initialization can only be detected, if at all, at
runtime and thus "undefined behavior" is a more appropriate treatment.
Nevertheless, it was deemed desirable to continue to require a
diagnostic for obvious compile-time cases.
</P>

<P>It was also noted that the current Standard does not say anything
about using a reference before it is initialized.  It seemed
reasonable to address both of these concerns in the same wording
proposed to resolve this issue.
</P>

<P><B>Notes from the April, 2005 meeting:</B></P>

<P>The CWG decided that whether to require an implementation to
diagnose initialization of a reference to itself should be handled as
a separate issue (504) and also suggested referring
to &#8220;storage&#8221; instead of &#8220;memory&#8221; (because
6.7.2 [<A href="https://wg21.link/intro.object">intro.object</A>] defines an object as a &#8220;region of
storage&#8221;).</P>

<P><B>Proposed Resolution (April, 2005) [SUPERSEDED]:</B></P>

<P>(Note: the following wording depends on the proposed
resolution for issue 232.)</P>

<P>Change 9.3.4.3 [<A href="https://wg21.link/dcl.ref#4">dcl.ref</A>] paragraph 4 as follows:</P>
<BLOCKQUOTE>

<P>
<DEL>A reference shall be initialized to refer to a valid object
or function.</DEL> <INS>If an lvalue to which a reference is directly
bound designates neither an existing object or function of an
appropriate type (9.4.4 [<A href="https://wg21.link/dcl.init.ref">dcl.init.ref</A>]), nor a region of
storage of suitable size and alignment to contain an object of the
reference's type (6.7.2 [<A href="https://wg21.link/intro.object">intro.object</A>], 6.7.3 [<A href="https://wg21.link/basic.life">basic.life</A>], 6.8 [<A href="https://wg21.link/basic.types">basic.types</A>]), the behavior is
undefined.</INS> [<I>Note:</I> in particular, a null reference cannot
exist in a well-defined program, because the only way to create
such a reference would be to bind it to the
<DEL>&#8220;object&#8221;</DEL> <INS>empty lvalue</INS> obtained by
dereferencing a null pointer, which <DEL>causes undefined behavior.
As</DEL> <INS>does not designate an object or function.  Also, as
</INS> described in 11.4.10 [<A href="https://wg21.link/class.bit">class.bit</A>],
a reference cannot be bound directly to a
bit-field. ]</P>

<P><INS>Any use of a reference before it is initialized results in
undefined behavior.  [<I>Example:</I>
</INS></P>

<INS>
<PRE>
  int&amp; f(int&amp;);
  int&amp; g();

  extern int&amp; ir3;
  int* ip = 0;

  int&amp; ir1 = *ip;     // <SPAN CLASS="cmnt">undefined behavior: null pointer</SPAN>
  int&amp; ir2 = f(ir3);  // <SPAN CLASS="cmnt">undefined behavior: </SPAN>ir3<SPAN CLASS="cmnt"> not yet initialized</SPAN>
  int&amp; ir3 = g();
  int&amp; ir4 = f(ir4);  // <SPAN CLASS="cmnt">undefined behavior: </SPAN>ir4<SPAN CLASS="cmnt"> used in its own initializer</SPAN>
</PRE>
&#8212;<I>end example</I>]
</INS>
</BLOCKQUOTE>

<P><B>Note (February, 2006):</B></P>

<P>The word &#8220;use&#8221; in the last
paragraph of the proposed resolution was intended to refer to the
description in 6.3 [<A href="https://wg21.link/basic.def.odr#2">basic.def.odr</A>] paragraph 2.  However, that
section does not define what it means for a reference to be
&#8220;used,&#8221; dealing only with objects and functions.  Additional
drafting is required to extend 6.3 [<A href="https://wg21.link/basic.def.odr#2">basic.def.odr</A>] paragraph 2
to apply to references.  </P>

<P><B>Additional note (May, 2008):</B></P>

<P>The proposed resolution for issue 570
adds wording to define &#8220;use&#8221; for references.</P>

<P><B>Note, January, 2012:</B></P>

<P>The resolution should also probably deal with the fact that
the &#8220;one-past-the-end&#8221; address of an array does not
designate a valid object (even if such a pointer might
&#8220;point to&#8221; an object of the correct type, per
6.8.4 [<A href="https://wg21.link/basic.compound">basic.compound</A>]) and thus is not suitable for the
lvalue-to-rvalue conversion.  </P>

<P><B>CWG 2023-11-06</B></P>

<P>We need a (possibly out-of-lifetime) object, not just a region of
storage here.  Empty lvalues do not exist.  Otherwise, the direction
is confirmed.</P>

<P><B>Proposed resolution (approved by CWG 2023-11-10) [SUPERSEDED]:</B></P>

<OL>
<LI>
<P>Change in 7.2.1 [<A href="https://wg21.link/basic.lval#11">basic.lval</A>] paragraph 11 as follows:</P>

<BLOCKQUOTE>

<P class="ins">
An object of dynamic type <TT>T</TT><I><SUB>obj</SUB></I>
is <I>type-accessible</I> through a glvalue of
type <TT>T</TT><I><SUB>ref</SUB></I>
if <TT>T</TT><I><SUB>ref</SUB></I> is similar
(7.3.6 [<A href="https://wg21.link/conv.qual">conv.qual</A>]) to:
<UL class="ins">
<LI>
<TT>T</TT><I><SUB>obj</SUB></I>,</LI>
<LI>a type that is the signed or unsigned type corresponding
to <TT>T</TT><I><SUB>obj</SUB></I>, or</LI>
<LI>a <TT>char</TT>, <TT>unsigned char</TT>, or <TT>std:byte</TT>
type.</LI>
</UL>

</P>

If a program attempts to access (3.1 [<A href="https://wg21.link/defns.access">defns.access</A>]) the stored
value of an object through a glvalue <DEL>whose type is not similar
(7.3.6 [<A href="https://wg21.link/conv.qual">conv.qual</A>]) to one of the following types</DEL>
<INS>through which it is not type-accessible,</INS> the behavior is
undefined<DEL>:</DEL><INS>.</INS>[ Footnote: ... ]
<UL class="del">
<LI>the dynamic type of the object,</LI>
<LI>a type that is the signed or unsigned type corresponding to
the dynamic type of the object, or</LI>
<LI>a char, unsigned char, or std::byte type.</LI>
</UL>

If a program invokes a defaulted copy/move constructor or copy/move
assignment operator for a union of type U with a glvalue argument that
does not denote an object of type cv U within its lifetime, the
behavior is undefined.

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 7.6.1.3 [<A href="https://wg21.link/expr.call#5">expr.call</A>] paragraph 5 as follows:</P>

<BLOCKQUOTE>

<INS>A type <TT>T</TT><I><SUB>call</SUB></I> is <I>call-compatible</I>
with a function type <TT>T</TT><I><SUB>func</SUB></I>
if <TT>T</TT><I><SUB>call</SUB></I> is the same type
as <TT>T</TT><I><SUB>func</SUB></I> or if the type "pointer
to <TT>T</TT><I><SUB>func</SUB></I>" can be converted to type "pointer
to <TT>T</TT><I><SUB>call</SUB></I>" via a function pointer conversion
(7.3.14 [<A href="https://wg21.link/conv.fctptr">conv.fctptr</A>]).</INS> Calling a function through an
expression whose function type <DEL>E is different from the
function</DEL> <INS>is not call-compatible with the</INS> type <DEL>F</DEL>
of the called function's definition results in undefined
behavior <DEL>unless the type &#8220;pointer to F&#8221; can be
converted to the type &#8220;pointer to E&#8221; via a function
pointer conversion (7.3.14 [<A href="https://wg21.link/conv.fctptr">conv.fctptr</A>])</DEL>.  [<I>Note
4:</I> <DEL>The exception applies</DEL> <INS>This requirement allows
the case</INS> when the expression has the type of a
potentially-throwing function, but the called function has a
non-throwing exception specification, and the function types are
otherwise the same. &#8212;<I>end note</I>]

</BLOCKQUOTE>
</LI>

<LI>
<P>Change and split in 9.3.4.3 [<A href="https://wg21.link/dcl.ref#5">dcl.ref</A>] paragraph 5 as follows:</P>

<BLOCKQUOTE>

<P>There shall be no references to references, no arrays of references,
and no pointers to references. The declaration of a reference shall
contain an initializer (9.4.4 [<A href="https://wg21.link/dcl.init.ref">dcl.init.ref</A>]) except when the
declaration contains an explicit extern specifier
(9.2.2 [<A href="https://wg21.link/dcl.stc">dcl.stc</A>]), is a class member
(11.4 [<A href="https://wg21.link/class.mem">class.mem</A>]) declaration within a class definition, or
is the declaration of a parameter or a return type
(9.3.4.6 [<A href="https://wg21.link/dcl.fct">dcl.fct</A>]); see 6.2 [<A href="https://wg21.link/basic.def">basic.def</A>].
<DEL>A reference shall be initialized to refer to a valid object or
function.</DEL>
</P>

<P>
<INS>Attempting to bind a reference to a function where the
initializer is a glvalue whose type is not call-compatible
(7.6.1.3 [<A href="https://wg21.link/expr.call">expr.call</A>]) with the type of the function's
definition results in undefined behavior. Attempting to bind a
reference to an object where the initializer is a glvalue through
which the object is not type-accessible (7.2.1 [<A href="https://wg21.link/basic.lval">basic.lval</A>])
results in undefined behavior.</INS> [<I>Note 2:</I> <DEL>In particular, a
null reference cannot exist in a well-defined program, because the
only way to create such a reference would be to bind it to the
&#8220;object&#8221; obtained by indirection through a null pointer,
which causes undefined behavior.</DEL>
<INS>The object designated by such a glvalue can be outside its
lifetime (6.7.3 [<A href="https://wg21.link/basic.life">basic.life</A>]). Because a null pointer value or
a pointer past the end of an object does not point to an object, a
reference in a well-defined program cannot refer to such things; see
7.6.2.2 [<A href="https://wg21.link/expr.unary.op">expr.unary.op</A>].</INS>
As described in 11.4.10 [<A href="https://wg21.link/class.bit">class.bit</A>], a reference cannot be
bound directly to a bit-field. &#8212;<I>end note</I>]
<INS>An odr-use (6.3 [<A href="https://wg21.link/basic.def.odr">basic.def.odr</A>]) of a reference that does not
happen after (6.9.2.2 [<A href="https://wg21.link/intro.races">intro.races</A>]) its initialization results
in undefined behavior. [ Example:</INS>
<PRE class="ins">
int &amp;f(int&amp;);
int &amp;g();
extern int &amp;ir3;
int *ip = 0;
int &amp;ir1 = *ip;    //<SPAN CLASS="cmnt"> undefined behavior: null pointer</SPAN>
int &amp;ir2 = f(ir3); //<SPAN CLASS="cmnt"> undefined behavior: </SPAN>ir3<SPAN CLASS="cmnt"> not yet initialized</SPAN>
int &amp;ir3 = g();
int &amp;ir4 = f(ir4); //<SPAN CLASS="cmnt"> undefined behavior: </SPAN>ir4<SPAN CLASS="cmnt"> used in its own initializer</SPAN>
</PRE>
<INS>-- end example ]</INS>
</P>

</BLOCKQUOTE>

</LI>

</OL>

<P><B>Additional notes (November, 2023):</B></P>

<P>An odr-use is a property of the program, not an evaluation that
participates in the "happens before" relation.</P>

<P><B>Proposed resolution (approved by CWG 2024-03-20):</B></P>

<OL>
<LI>
<P>Change in 7.2.1 [<A href="https://wg21.link/basic.lval#11">basic.lval</A>] paragraph 11 as follows:</P>

<BLOCKQUOTE>

<P class="ins">
An object of dynamic type <TT>T</TT><I><SUB>obj</SUB></I>
is <I>type-accessible</I> through a glvalue of
type <TT>T</TT><I><SUB>ref</SUB></I>
if <TT>T</TT><I><SUB>ref</SUB></I> is similar
(7.3.6 [<A href="https://wg21.link/conv.qual">conv.qual</A>]) to:
<UL class="ins">
<LI>
<TT>T</TT><I><SUB>obj</SUB></I>,</LI>
<LI>a type that is the signed or unsigned type corresponding
to <TT>T</TT><I><SUB>obj</SUB></I>, or</LI>
<LI>a <TT>char</TT>, <TT>unsigned char</TT>, or <TT>std:byte</TT>
type.</LI>
</UL>

</P>

If a program attempts to access (3.1 [<A href="https://wg21.link/defns.access">defns.access</A>]) the stored
value of an object through a glvalue <DEL>whose type is not similar
(7.3.6 [<A href="https://wg21.link/conv.qual">conv.qual</A>]) to one of the following types</DEL>
<INS>through which it is not type-accessible,</INS> the behavior is
undefined<DEL>:</DEL><INS>.</INS>[ Footnote: ... ]
<UL class="del">
<LI>the dynamic type of the object,</LI>
<LI>a type that is the signed or unsigned type corresponding to
the dynamic type of the object, or</LI>
<LI>a char, unsigned char, or std::byte type.</LI>
</UL>

If a program invokes a defaulted copy/move constructor or copy/move
assignment operator for a union of type U with a glvalue argument that
does not denote an object of type cv U within its lifetime, the
behavior is undefined.

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 7.6.1.3 [<A href="https://wg21.link/expr.call#5">expr.call</A>] paragraph 5 as follows:</P>

<BLOCKQUOTE>

<INS>A type <TT>T</TT><I><SUB>call</SUB></I> is <I>call-compatible</I>
with a function type <TT>T</TT><I><SUB>func</SUB></I>
if <TT>T</TT><I><SUB>call</SUB></I> is the same type
as <TT>T</TT><I><SUB>func</SUB></I> or if the type "pointer
to <TT>T</TT><I><SUB>func</SUB></I>" can be converted to type "pointer
to <TT>T</TT><I><SUB>call</SUB></I>" via a function pointer conversion
(7.3.14 [<A href="https://wg21.link/conv.fctptr">conv.fctptr</A>]).</INS> Calling a function through an
expression whose function type <DEL>E is different from the
function</DEL> <INS>is not call-compatible with the</INS> type <DEL>F</DEL>
of the called function's definition results in undefined
behavior <DEL>unless the type &#8220;pointer to F&#8221; can be
converted to the type &#8220;pointer to E&#8221; via a function
pointer conversion (7.3.14 [<A href="https://wg21.link/conv.fctptr">conv.fctptr</A>])</DEL>.  [<I>Note
4:</I> <DEL>The exception applies</DEL> <INS>This requirement allows
the case</INS> when the expression has the type of a
potentially-throwing function, but the called function has a
non-throwing exception specification, and the function types are
otherwise the same. &#8212;<I>end note</I>]

</BLOCKQUOTE>
</LI>

<LI>
<P>Change and split in 9.3.4.3 [<A href="https://wg21.link/dcl.ref#5">dcl.ref</A>] paragraph 5 as follows:</P>

<BLOCKQUOTE>

<P>There shall be no references to references, no arrays of references,
and no pointers to references. The declaration of a reference shall
contain an initializer (9.4.4 [<A href="https://wg21.link/dcl.init.ref">dcl.init.ref</A>]) except when the
declaration contains an explicit extern specifier
(9.2.2 [<A href="https://wg21.link/dcl.stc">dcl.stc</A>]), is a class member
(11.4 [<A href="https://wg21.link/class.mem">class.mem</A>]) declaration within a class definition, or
is the declaration of a parameter or a return type
(9.3.4.6 [<A href="https://wg21.link/dcl.fct">dcl.fct</A>]); see 6.2 [<A href="https://wg21.link/basic.def">basic.def</A>].
<DEL>A reference shall be initialized to refer to a valid object or
function.</DEL>
</P>

<P>
<INS>Attempting to bind a reference to a function where the
converted initializer is a glvalue whose type is not call-compatible
(7.6.1.3 [<A href="https://wg21.link/expr.call">expr.call</A>]) with the type of the function's
definition results in undefined behavior. Attempting to bind a
reference to an object where the converted initializer is a glvalue through
which the object is not type-accessible (7.2.1 [<A href="https://wg21.link/basic.lval">basic.lval</A>])
results in undefined behavior.</INS> [<I>Note 2:</I> <DEL>In particular, a
null reference cannot exist in a well-defined program, because the
only way to create such a reference would be to bind it to the
&#8220;object&#8221; obtained by indirection through a null pointer,
which causes undefined behavior.</DEL>
<INS>The object designated by such a glvalue can be outside its
lifetime (6.7.3 [<A href="https://wg21.link/basic.life">basic.life</A>]). Because a null pointer value or
a pointer past the end of an object does not point to an object, a
reference in a well-defined program cannot refer to such things; see
7.6.2.2 [<A href="https://wg21.link/expr.unary.op">expr.unary.op</A>].</INS>
As described in 11.4.10 [<A href="https://wg21.link/class.bit">class.bit</A>], a reference cannot be
bound directly to a bit-field. &#8212;<I>end note</I>]
<INS>The behavior of an evaluation of a reference
(7.5.4 [<A href="https://wg21.link/expr.prim.id">expr.prim.id</A>], 7.6.1.5 [<A href="https://wg21.link/expr.ref">expr.ref</A>]) that does
not happen after (6.9.2.2 [<A href="https://wg21.link/intro.races">intro.races</A>]) the initialization of
the reference is undefined.  [ Example:</INS>
<PRE class="ins">
int &amp;f(int&amp;);
int &amp;g();
extern int &amp;ir3;
int *ip = 0;
int &amp;ir1 = *ip;    //<SPAN CLASS="cmnt"> undefined behavior: null pointer</SPAN>
int &amp;ir2 = f(ir3); //<SPAN CLASS="cmnt"> undefined behavior: </SPAN>ir3<SPAN CLASS="cmnt"> not yet initialized</SPAN>
int &amp;ir3 = g();
int &amp;ir4 = f(ir4); //<SPAN CLASS="cmnt"> undefined behavior: </SPAN>ir4<SPAN CLASS="cmnt"> used in its own initializer</SPAN>

char x alignas(int);
int &amp;ir5 = *reinterpret_cast&lt;int *&gt;(&amp;x);  // <SPAN CLASS="cmnt">undefined behavior: initializer refers to char object</SPAN>
</PRE>
<INS>-- end example ]</INS>
</P>

</BLOCKQUOTE>

</LI>
</OL>

<BR><BR><HR>
<A NAME="1954"></A><H4>1954.
  
<TT>typeid</TT> null dereference check in subexpressions
</H4>
<B>Section: </B>7.6.1.8&#160; [<A href="https://wg21.link/expr.typeid">expr.typeid</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>David Majnemer
 &#160;&#160;&#160;

 <B>Date: </B>2014-06-23


<P>According to 7.6.1.8 [<A href="https://wg21.link/expr.typeid#2">expr.typeid</A>] paragraph 2,</P>

<BLOCKQUOTE>

If the glvalue expression is obtained by applying the
unary <TT>*</TT> operator to a pointer<SUP>69</SUP> and the
pointer is a null pointer value (7.3.12 [<A href="https://wg21.link/conv.ptr">conv.ptr</A>]),
the <TT>typeid</TT> expression throws an exception
(14.2 [<A href="https://wg21.link/except.throw">except.throw</A>]) of a type that would match a
handler of type
<TT>std::bad_typeid</TT> exception (17.7.5 [<A href="https://wg21.link/bad.typeid">bad.typeid</A>]).

</BLOCKQUOTE>

<P>The footnote makes clear that this requirement applies without
regard to parentheses, but it is unspecified whether it applies when
the dereference occurs in a subexpression of the operand (e.g., in
the second operand of the comma operator or the second or third
operand of a conditional operator).  There is implementation
divergence on this question.</P>

<P><B>Proposed resolution (approved by CWG 2023-11-09):</B></P>

<P>Insert a new paragraph before 7.6.1.8 [<A href="https://wg21.link/expr.typeid#3">expr.typeid</A>] paragraph 3
and change the latter as follows:</P>

<BLOCKQUOTE>

<P class="ins">
If an <I>expression</I> operand of <TT>typeid</TT> is a
possibly-parenthesized <I>unary-expression</I>
whose <I>unary-operator</I> is <TT>*</TT> and whose operand evaluates
to a null pointer value (6.8.4 [<A href="https://wg21.link/basic.compound">basic.compound</A>]),
the <TT>typeid</TT> expression throws an exception
(14.2 [<A href="https://wg21.link/except.throw">except.throw</A>]) of a type that would match a handler of
type <TT>std::bad_typeid</TT> (17.7.5 [<A href="https://wg21.link/bad.typeid">bad.typeid</A>]). [ Note:
In other contexts, evaluating such a <I>unary-expression</I> results
in undefined behavior (7.6.2.2 [<A href="https://wg21.link/expr.unary.op">expr.unary.op</A>]) -- end note ]
</P>

<P>
When typeid is applied to a glvalue whose type is a polymorphic class
type (11.7.3 [<A href="https://wg21.link/class.virtual">class.virtual</A>]), the result refers to a
std::type_info object representing the type of the most derived object
(6.7.2 [<A href="https://wg21.link/intro.object">intro.object</A>]) (that is, the dynamic type) to which the
glvalue refers. <DEL>If the glvalue is obtained by applying the unary *
operator to a pointer [ Footnote: ... ] and the pointer is a null
pointer value (6.8.4 [<A href="https://wg21.link/basic.compound">basic.compound</A>]), the typeid expression
throws an exception (14.2 [<A href="https://wg21.link/except.throw">except.throw</A>]) of a type that would
match a handler of type std::bad_typeid exception
(17.7.5 [<A href="https://wg21.link/bad.typeid">bad.typeid</A>]).</DEL>
</P>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2476"></A><H4>2476.
  
<I>placeholder-type-specifier</I>s and function declarators
</H4>
<B>Section: </B>9.2.9.7.1&#160; [<A href="https://wg21.link/dcl.spec.auto.general">dcl.spec.auto.general</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Davis Herring
 &#160;&#160;&#160;

 <B>Date: </B>2021-01-29




<P>According to 9.2.9.7.1 [<A href="https://wg21.link/dcl.spec.auto.general#3">dcl.spec.auto.general</A>] paragraph 3,</P>

<BLOCKQUOTE>

The placeholder type can appear with a function declarator
in the <I>decl-specifier-seq</I>, <I>type-specifier-seq</I>,
<I>conversion-function-id</I>,
or <I>trailing-return-type</I>, in any context where such a
declarator is valid. If the function declarator includes
a <I>trailing-return-type</I> (9.3.4.6 [<A href="https://wg21.link/dcl.fct">dcl.fct</A>]),
that <I>trailing-return-type</I> specifies the declared
return type of the function. Otherwise, the function
declarator shall declare a function.

</BLOCKQUOTE>

<P>This wording disallows a declaration like</P>

<PRE>
   int f();
   auto (*fp)()=f;
</PRE>

<P>The requirement to declare a function was introduced by
the resolution of issue 1892.</P>

<P><B>Proposed resolution (April, 2021) [SUPERSEDED]:</B></P>

<P>Change 9.2.9.7.1 [<A href="https://wg21.link/dcl.spec.auto.general#3">dcl.spec.auto.general</A>] paragraph 3 as follows:</P>

<BLOCKQUOTE>

The placeholder type can appear with a function declarator
in the <I>decl-specifier-seq</I>, <I>type-specifier-seq</I>,
<I>conversion-function-id</I>, or <I>trailing-return-type</I><DEL>,
in any context where such a declarator is valid</DEL>
<INS>if the function declarator includes a
<I>trailing-return-type</I> <TT>T</TT>
(9.3.4.6 [<A href="https://wg21.link/dcl.fct">dcl.fct</A>]) or declares a function</INS>.
<DEL>If the function declarator includes
a <I>trailing-return-type</I> (9.3.4.6 [<A href="https://wg21.link/dcl.fct">dcl.fct</A>]),
that <I>trailing-return-type</I> specifies</DEL>
<INS>In the former case, <TT>T</TT> is</INS> the declared
return type of the function. <DEL>Otherwise, the function
declarator shall declare a function.</DEL> If the declared
return type of <DEL>the</DEL> <INS>a</INS> function contains
a placeholder type, the return type of the function is
deduced from non-discarded <TT>return</TT> statements, if
any, in the body of the function (8.5.2 [<A href="https://wg21.link/stmt.if">stmt.if</A>]).

</BLOCKQUOTE>

<P><B>Additional notes (May, 2021):</B></P>

<P>It was observed  that the proposed resolution above does not
address the example in the issue, since <TT>fp</TT> neither has
a <I>trailing-return-type</I> nor declares a function. Presumably
another case in which a function declarator with a placeholder
return type should be permitted is in the declaration of a
variable in which the type is deduced from its initializer.</P>

<P>It was also noted in passing that the deduction in the
example is only partial: the parameter-type-list is
specified by the declarator and only the return type is
deduced from the initializer.  Although this example is
supported by current implementations, there is
implementation divergence in the support of another case in
which only part of the variable's type is deduced:</P>

<PRE>
    auto (&amp;ar)[2] = L"a";  //<SPAN CLASS="cmnt"> Array bound declared, element type deduced</SPAN>
</PRE>

<P>This issue is related to issue 1892,
which prohibited cases like</P>

<PRE>
    std::vector&lt;auto(*)()&gt; v;
</PRE>

<P>The ultimate outcome of the two issues should be:</P>

<PRE>
    int f();
    auto (*fp1)() = f;       //<SPAN CLASS="cmnt"> OK</SPAN>
    auto (*fp2)()-&gt;int = f;  //<SPAN CLASS="cmnt"> OK</SPAN>
    auto (*fp3)()-&gt;auto = f; //<SPAN CLASS="cmnt"> OK</SPAN>

    template&lt;typename T&gt; struct C { };
    C&lt;auto(*)()&gt; c1;         //<SPAN CLASS="cmnt"> Not OK</SPAN>
    C&lt;auto(*)()-&gt;int&gt; c2;    //<SPAN CLASS="cmnt"> OK</SPAN>
    C&lt;auto(*)()-&gt;auto&gt; c3;   //<SPAN CLASS="cmnt"> Not OK</SPAN>
</PRE>

<P><B>Proposed resolution (January, 2023) [SUPERSEDED]:</B></P>

<OL>

<LI>

<P>Change in 9.2.9.7.1 [<A href="https://wg21.link/dcl.spec.auto.general#1">dcl.spec.auto.general</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

A <I>placeholder-type-specifier</I> designates a placeholder type that
will be replaced later<INS>, typically</INS> by deduction from an
initializer.

</BLOCKQUOTE>

</LI>

<LI>

<P>Change and split 9.2.9.7.1 [<A href="https://wg21.link/dcl.spec.auto.general#3">dcl.spec.auto.general</A>] paragraph 3 as follows:</P>

<BLOCKQUOTE>

<P>
A placeholder type can appear <DEL>with a function declarator</DEL> in
the <I>decl-specifier-seq</I><DEL>, <I>type-specifier-seq</I>,
<I>conversion-function-id</I>, or <I>trailing-return-type</I>, in any
context where such</DEL> <INS>for</INS> a <INS>function</INS>
declarator <DEL>is valid</DEL> <INS>that includes
a <I>trailing-return-type</I>
(9.3.4.6 [<A href="https://wg21.link/dcl.fct">dcl.fct</A>])</INS>. <DEL>If the function declarator
includes a <I>trailing-return-type</I> (9.3.4.6 [<A href="https://wg21.link/dcl.fct">dcl.fct</A>]),
that <I>trailing-return-type</I> specifies the declared return type of
the function.</DEL>
</P>

<P>
<DEL>Otherwise, the</DEL> <INS>A placeholder type can appear in
the <I>decl-specifier-seq</I> or <I>type-specifier-seq</I> in the
declared return type of a</INS> function declarator <DEL>shall
declare</DEL> <INS>that declares</INS> a function<DEL>. If the
declared return type of the function contains a placeholder
type,</DEL> <INS>;</INS> the return type of the function is deduced
from non-discarded <TT>return</TT> statements, if any, in the body of
the function (8.5.2 [<A href="https://wg21.link/stmt.if">stmt.if</A>]).
</P>

</BLOCKQUOTE>

</LI>

<LI>

<P>Change in 9.2.9.7.1 [<A href="https://wg21.link/dcl.spec.auto.general#4">dcl.spec.auto.general</A>] paragraph 4 as follows:</P>

<BLOCKQUOTE>

The type of a variable declared using a placeholder type is deduced
from its initializer. This use is allowed in an initializing
declaration (9.4 [<A href="https://wg21.link/dcl.init">dcl.init</A>]) of a variable. The placeholder
type shall appear as one of the <I>decl-specifier</I>s in
the <I>decl-specifier-seq</I> <DEL>and</DEL> <INS>or as one of
the <I>type-specifier</I>s in a <I>trailing-return-type</I> that
specifies the type that replaces such a <I>decl-specifier</I>;</INS>
the <I>decl-specifier-seq</I> shall be followed by one or
more <I>declarator</I>s, each of which shall be followed by a
non-empty <I>initializer</I>. [ Example:

<PRE>
  ...
  auto f() -&gt; int;                //<SPAN CLASS="cmnt"> OK, f returns int</SPAN>
  <INS>auto (*fp)() -&gt; auto = f;       // <SPAN CLASS="cmnt">OK</SPAN></INS>
  ...
</PRE>
-- end example ]
</BLOCKQUOTE>

</LI>

<LI>

<P>Change in 9.3.4.6 [<A href="https://wg21.link/dcl.fct#1">dcl.fct</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>
In a declaration T D where D has the form
<PRE>
D1 ( <I>parameter-declaration-clause</I> ) <I>cv-qualifier-seq<sub>opt</sub>
  ref-qualifier<sub>opt</sub> noexcept-specifier<sub>opt</sub> attribute-specifier-seq<sub>opt</sub> <INS>trailing-return-type<sub>opt</sub></INS></I>
</PRE>

and the type of the contained <I>declarator-id</I> in the
declaration <TT>T D1</TT> is
"<I>derived-declarator-type-list</I> <TT>T</TT>"<DEL>,</DEL><INS>:</INS>

<UL class="ins">

<LI>If the <I>trailing-return-type</I> is present, <TT>T</TT> shall be
the single <I>type-specifier</I> <TT>auto</TT>, and the declared
return type of the function type is the type specified by
the <I>trailing-return-type</I>.</LI>

<LI>Otherwise, the declared return type of the function type
is <TT>T</TT>.</LI>

</UL>

<DEL>the</DEL><INS>The</INS> type of the <I>declarator-id</I> in <TT>D</TT> is
"<I>derived-declarator-type-list</I> noexceptopt function of
parameter-type-list <I>cv-qualifier-seqopt ref-qualifieropt</I> returning
<DEL>T</DEL> <INS>U</INS>", where

<UL>

<LI>the parameter-type-list is derived from the <I>parameter-declaration-clause</I> as described below<INS>,</INS>
</LI>

<LI>
<INS><TT>U</TT> is the declared return type,</INS> and</LI>

<LI>the optional noexcept is present if and only if the exception
specification (14.5 [<A href="https://wg21.link/except.spec">except.spec</A>]) is non-throwing.</LI>

</UL>

The optional <I>attribute-specifier-seq</I> appertains to the function type.

</BLOCKQUOTE>

</LI>

<LI>

<P>Remove 9.3.4.6 [<A href="https://wg21.link/dcl.fct#2">dcl.fct</A>] paragraph 2:</P>

<BLOCKQUOTE>

<DEL>
In a declaration T D where D has the form
<PRE>
<DEL>D1 ( <I>parameter-declaration-clause</I> ) <I>cv-qualifier-seqopt
  ref-qualifieropt noexcept-specifieropt attribute-specifier-seqopt trailing-return-type</I></DEL>
</PRE>

and the type ...  The optional attribute-specifier-seq appertains to the
function type.</DEL>

</BLOCKQUOTE>

</LI>

<LI>

<P>Change in 11.4.8.3 [<A href="https://wg21.link/class.conv.fct#1">class.conv.fct</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

A declaration whose <I>declarator-id</I> has an <I>unqualified-id</I>
that is a <I>conversion-function-id</I> declares a conversion
function; its declarator shall be a function declarator
(9.3.4.6 [<A href="https://wg21.link/dcl.fct">dcl.fct</A>]) of the form
<PRE>
<I><DEL>ptr-declarator</DEL> <INS>noptr-declarator</INS></I> <DEL>( <I>parameter-declaration-clause</I> ) <I>cv-qualifier-seqopt
      ref-qualifier-seqopt noexcept-specifieropt attribute-specifier-seqopt</I></DEL> <INS>parameters-and-qualifiers</INS>
</PRE>
where the <I><DEL>ptr-declarator</DEL> <INS>noptr-declarator</INS></I>
consists solely of an <I>id-expression</I>, an
optional <I>attribute-specifier-seq</I>, and optional surrounding
parentheses, and the <I>id-expression</I> has one of the following
forms: ...

</BLOCKQUOTE>

</LI>

<LI>

<P>Change in 11.4.8.3 [<A href="https://wg21.link/class.conv.fct#2">class.conv.fct</A>] paragraph 2 as follows:</P>

<BLOCKQUOTE>

A conversion function shall have no non-object parameters and shall be
a non-static member function of a class or class template X;
<INS>its declared return type is the <I>conversion-type-id</I>
and</INS> it specifies a conversion from <TT>X</TT> to the type
specified by the <I>conversion-type-id</I> interpreted as
a <I>type-id</I> (9.3.2 [<A href="https://wg21.link/dcl.name">dcl.name</A>]). A <I>decl-specifier</I>
in the <I>decl-specifier-seq</I> of a conversion function (if any)
shall not be a <I>defining-type-specifier</I> .

</BLOCKQUOTE>

</LI>

<LI>

<P>Remove 11.4.8.3 [<A href="https://wg21.link/class.conv.fct#3">class.conv.fct</A>] paragraph 3:</P>

<BLOCKQUOTE>

<DEL>The type of the conversion function is &#8220;noexceptopt function
taking no parameter <I>cv-qualifier-seq</I> opt <I>ref-qualifier</I>
opt returning <I>conversion-type-id</I>&#8221;.</DEL>

</BLOCKQUOTE>

</LI>

</OL>

<P><B>CWG 2023-06</B></P>

<P>This does not address <TT>void f2(auto (*)() -&gt; auto);</TT>
</P>

<P><B>Proposed resolution (approved by CWG 2023-11-10):</B></P>

<OL>

<LI>

<P>Change in 9.2.9.7.1 [<A href="https://wg21.link/dcl.spec.auto.general#1">dcl.spec.auto.general</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

A <I>placeholder-type-specifier</I> designates a placeholder type that
will be replaced later<INS>, typically</INS> by deduction from an
initializer.

</BLOCKQUOTE>

</LI>

<LI>

<P>Change 9.2.9.7.1 [<A href="https://wg21.link/dcl.spec.auto.general#2">dcl.spec.auto.general</A>] paragraph 2 as follows:</P>

<BLOCKQUOTE>

<DEL>A</DEL> <INS>The type of a <I>parameter-declaration</I> of a
function declaration
(9.3.4.6 [<A href="https://wg21.link/dcl.fct">dcl.fct</A>]), <I>lambda-expression</I>
(7.5.5 [<A href="https://wg21.link/expr.prim.lambda">expr.prim.lambda</A>])<INS>, or <I>template-parameter</I>
(13.2 [<A href="https://wg21.link/temp.param">temp.param</A>])</INS> can be declared using
a</INS> <I>placeholder-type-specifier</I> of the form
<I>type-constraint</I><SUB>opt</SUB> <TT>auto</TT> <DEL>can be used as
a <I>decl-specifier</I> of the <I>decl-specifier-seq</I> of
a <I>parameter-declaration</I> of a function declaration
or <I>lambda-expression</I> and, if it is not the
auto <I>type-specifier</I> introducing</DEL><INS>. The placeholder type
shall appear as one of the <I>decl-specifier</I>s in
the <I>decl-specifier-seq</I> or as one of the <I>type-specifier</I>s
in</INS> a <I>trailing-return-type</I> <DEL>,</DEL> <INS>that
specifies the type that replaces such a <I>decl-specifier</I></INS>
(see below)<INS>; the placeholder type</INS> is a <I>generic parameter
type placeholder</I> of the function declaration
<DEL>or</DEL><INS>,</INS> <I>lambda-expression</I><INS>,
or <I>template-parameter</I>, respectively</INS>.

</BLOCKQUOTE>

</LI>

<LI>

<P>Change and split 9.2.9.7.1 [<A href="https://wg21.link/dcl.spec.auto.general#3">dcl.spec.auto.general</A>] paragraph 3 as follows:</P>

<BLOCKQUOTE>

<P>
A placeholder type can appear <DEL>with a function declarator</DEL> in
the <I>decl-specifier-seq</I><DEL>, <I>type-specifier-seq</I>,
<I>conversion-function-id</I>, or <I>trailing-return-type</I>, in any
context where such</DEL> <INS>for</INS> a <INS>function</INS>
declarator <DEL>is valid</DEL> <INS>that includes
a <I>trailing-return-type</I>
(9.3.4.6 [<A href="https://wg21.link/dcl.fct">dcl.fct</A>])</INS>. <DEL>If the function declarator
includes a <I>trailing-return-type</I> (9.3.4.6 [<A href="https://wg21.link/dcl.fct">dcl.fct</A>]),
that <I>trailing-return-type</I> specifies the declared return type of
the function.</DEL>
</P>

<P>
<DEL>Otherwise, the</DEL> <INS>A placeholder type can appear in
the <I>decl-specifier-seq</I> or <I>type-specifier-seq</I> in the
declared return type of a</INS> function declarator <DEL>shall
declare</DEL> <INS>that declares</INS> a function<DEL>. If the
declared return type of the function contains a placeholder
type,</DEL> <INS>;</INS> the return type of the function is deduced
from non-discarded <TT>return</TT> statements, if any, in the body of
the function (8.5.2 [<A href="https://wg21.link/stmt.if">stmt.if</A>]).
</P>

</BLOCKQUOTE>

</LI>

<LI>

<P>Change in 9.2.9.7.1 [<A href="https://wg21.link/dcl.spec.auto.general#4">dcl.spec.auto.general</A>] paragraph 4 as follows:</P>

<BLOCKQUOTE>

The type of a variable declared using a placeholder type is deduced
from its initializer. This use is allowed in an initializing
declaration (9.4 [<A href="https://wg21.link/dcl.init">dcl.init</A>]) of a variable. The placeholder
type shall appear as one of the <I>decl-specifier</I>s in
the <I>decl-specifier-seq</I> <DEL>and</DEL> <INS>or as one of
the <I>type-specifier</I>s in a <I>trailing-return-type</I> that
specifies the type that replaces such a <I>decl-specifier</I>;</INS>
the <I>decl-specifier-seq</I> shall be followed by one or
more <I>declarator</I>s, each of which shall be followed by a
non-empty <I>initializer</I>. [ Example:

<PRE>
  ...
  auto f() -&gt; int;                //<SPAN CLASS="cmnt"> OK, f returns int</SPAN>
  <INS>auto (*fp)() -&gt; auto = f;       // <SPAN CLASS="cmnt">OK</SPAN></INS>
  ...
</PRE>
-- end example ]
</BLOCKQUOTE>

</LI>

<LI>

<P>Change and split 9.2.9.7.1 [<A href="https://wg21.link/dcl.spec.auto.general#5">dcl.spec.auto.general</A>] paragraph 5 as follows:</P>

<BLOCKQUOTE>

<P>A placeholder type can also be used in the <I>type-specifier-seq</I>
<DEL>in</DEL> <INS>of</INS> the <I>new-type-id</I> or <INS>in
the</INS> <I>type-id</I> of a <I>new-expression</I>
(7.6.2.8 [<A href="https://wg21.link/expr.new">expr.new</A>]) <DEL>and as a <I>decl-specifier</I> of
the <I>parameter-declaration</I>'s <I>decl-specifier-seq</I> in
a <I>template-parameter</I> (13.2 [<A href="https://wg21.link/temp.param">temp.param</A>])</DEL>.
<INS>In such a <I>type-id</I>, the placeholder type shall appear as one of the <I>type-specifier</I>s in the <I>type-specifier-seq</I> or as one of the <I>type-specifier</I>s in a <I>trailing-return-type</I> that specifies the type that replaces such a <I>type-specifier</I>.</INS>
</P>

<P>The <TT>auto</TT> <I>type-specifier</I> can also be used as
the <I>simple-type-specifier</I> in an explicit type conversion
(functional notation) (7.6.1.4 [<A href="https://wg21.link/expr.type.conv">expr.type.conv</A>]).</P>

</BLOCKQUOTE>

</LI>

<LI>

<P>Change in 9.3.4.6 [<A href="https://wg21.link/dcl.fct#1">dcl.fct</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>
In a declaration T D where <INS><TT>T</TT> may be empty and</INS> D has the form
<PRE>
D1 ( <I>parameter-declaration-clause</I> ) <I>cv-qualifier-seq<sub>opt</sub>
  ref-qualifier<sub>opt</sub> noexcept-specifier<sub>opt</sub> attribute-specifier-seq<sub>opt</sub> <INS>trailing-return-type<sub>opt</sub></INS></I>
</PRE>

<INS>a <I>derived-declarator-type-list</I> is determined as follows:</INS>
<DEL>and</DEL>

<UL>
<LI class="ins">If the <I>unqualified-id</I> of the <I>declarator-id</I> is
a <I>conversion-function-id</I>,
the <I>derived-declarator-type-list</I> is empty.</LI>
<LI>
<INS>Otherwise, the <I>derived-declarator-type-list</I> is as
appears in</INS> the
type <INS>"<I>derived-declarator-type-list</I> <TT>T</TT>"</INS> of
the contained <I>declarator-id</I> in the declaration <TT>T
D1</TT>
<DEL>is "<I>derived-declarator-type-list</I> <TT>T</TT>"</DEL>.</LI>
</UL>

<INS>The declared return type <TT>U</TT> of the function type is
determined as follows:</INS>

<UL class="ins">

<LI>If the <I>trailing-return-type</I> is present, <TT>T</TT> shall be
the single <I>type-specifier</I> <TT>auto</TT>, and <TT>U</TT> is the
type specified by the <I>trailing-return-type</I>.</LI>

<LI>Otherwise, if the declaration declares a conversion
function, see 11.4.8.3 [<A href="https://wg21.link/class.conv.fct">class.conv.fct</A>].</LI>

<LI>Otherwise, <TT>U</TT> is <TT>T</TT>.</LI>

</UL>

<DEL>the</DEL><INS>The</INS> type of the <I>declarator-id</I> in <TT>D</TT> is
"<I>derived-declarator-type-list</I> noexceptopt function of
parameter-type-list <I>cv-qualifier-seqopt ref-qualifieropt</I> returning
<DEL>T</DEL> <INS>U</INS>", where

<UL>

<LI>the parameter-type-list is derived from the <I>parameter-declaration-clause</I> as described below and</LI>

<LI>the optional noexcept is present if and only if the exception
specification (14.5 [<A href="https://wg21.link/except.spec">except.spec</A>]) is non-throwing.</LI>

</UL>

The optional <I>attribute-specifier-seq</I> appertains to the function type.

</BLOCKQUOTE>

</LI>

<LI>

<P>Remove 9.3.4.6 [<A href="https://wg21.link/dcl.fct#2">dcl.fct</A>] paragraph 2:</P>

<BLOCKQUOTE>

<DEL>
In a declaration T D where D has the form
<PRE>
<DEL>D1 ( <I>parameter-declaration-clause</I> ) <I>cv-qualifier-seqopt
  ref-qualifieropt noexcept-specifieropt attribute-specifier-seqopt trailing-return-type</I></DEL>
</PRE>

and the type ...  The optional attribute-specifier-seq appertains to the
function type.</DEL>

</BLOCKQUOTE>

</LI>

<LI>

<P>Change in 11.4.8.3 [<A href="https://wg21.link/class.conv.fct#1">class.conv.fct</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

A declaration whose <I>declarator-id</I> has an <I>unqualified-id</I>
that is a <I>conversion-function-id</I> declares a conversion
function; its declarator shall be a function declarator
(9.3.4.6 [<A href="https://wg21.link/dcl.fct">dcl.fct</A>]) of the form
<PRE>
<I><DEL>ptr-declarator</DEL> <INS>noptr-declarator</INS></I> <DEL>( <I>parameter-declaration-clause</I> ) <I>cv-qualifier-seqopt
      ref-qualifier-seqopt noexcept-specifieropt attribute-specifier-seqopt</I></DEL> <INS>parameters-and-qualifiers</INS>
</PRE>
where the <I><DEL>ptr-declarator</DEL> <INS>noptr-declarator</INS></I>
consists solely of an <I>id-expression</I>, an
optional <I>attribute-specifier-seq</I>, and optional surrounding
parentheses, and the <I>id-expression</I> has one of the following
forms: ...

</BLOCKQUOTE>

</LI>

<LI>

<P>Change in 11.4.8.3 [<A href="https://wg21.link/class.conv.fct#2">class.conv.fct</A>] paragraph 2 as follows:</P>

<BLOCKQUOTE>

A conversion function shall have no non-object parameters and shall be
a non-static member function of a class or class template X;
<INS>its declared return type is the <I>conversion-type-id</I>
and</INS> it specifies a conversion from <TT>X</TT> to the type
specified by the <I>conversion-type-id</I> interpreted as
a <I>type-id</I> (9.3.2 [<A href="https://wg21.link/dcl.name">dcl.name</A>]). A <I>decl-specifier</I>
in the <I>decl-specifier-seq</I> of a conversion function (if any)
shall not be a <I>defining-type-specifier</I> .

</BLOCKQUOTE>

</LI>

<LI>

<P>Remove 11.4.8.3 [<A href="https://wg21.link/class.conv.fct#3">class.conv.fct</A>] paragraph 3:</P>

<BLOCKQUOTE>

<DEL>The type of the conversion function is &#8220;noexceptopt function
taking no parameter <I>cv-qualifier-seq</I> opt <I>ref-qualifier</I>
opt returning <I>conversion-type-id</I>&#8221;.</DEL>

</BLOCKQUOTE>

</LI>

</OL>

<BR><BR><HR>
<A NAME="2533"></A><H4>2533.
  
Storage duration of implicitly created objects
</H4>
<B>Section: </B>6.7.5&#160; [<A href="https://wg21.link/basic.stc">basic.stc</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Andrey Erokhin
 &#160;&#160;&#160;

 <B>Date: </B>2022-02-17




<P>In subclause 6.7.2 [<A href="https://wg21.link/intro.object#10">intro.object</A>] paragraph 10,
operations implicitly creating objects are defined:</P>

<BLOCKQUOTE>

Some operations are described as <I>implicitly creating objects</I>
within a specified region of storage. For each operation that is
specified as implicitly creating objects, that operation implicitly
creates and starts the lifetime of zero or more objects of
implicit-lifetime types (6.8.1 [<A href="https://wg21.link/basic.types.general">basic.types.general</A>]) in its specified
region of storage if...

</BLOCKQUOTE>

<P>However, the standard does not specify the storage duration that
such an implicitly-created object has; this new method of object
creation is not mentioned in 6.7.5.1 [<A href="https://wg21.link/basic.stc.general#2">basic.stc.general</A>] paragraph 2:</P>

<BLOCKQUOTE>

Static, thread, and automatic storage durations are associated with
objects introduced by declarations (6.2 [<A href="https://wg21.link/basic.def">basic.def</A>]) and
implicitly created by the implementation
(6.7.7 [<A href="https://wg21.link/class.temporary">class.temporary</A>]). The dynamic storage duration is
associated with objects created by a <I>new-expression</I>
(7.6.2.8 [<A href="https://wg21.link/expr.new">expr.new</A>]).

</BLOCKQUOTE>

<P>With the exception of <TT>malloc</TT>, the storage duration should
probably be that of the object providing storage (if any), similar to
the provision for subobjects in 6.7.5.6 [<A href="https://wg21.link/basic.stc.inherit">basic.stc.inherit</A>]:</P>

<BLOCKQUOTE>

The storage duration of subobjects and reference members is that of
their complete object (6.7.2 [<A href="https://wg21.link/intro.object">intro.object</A>]).

</BLOCKQUOTE>

<P>The storage duration of an object created by a non-allocating form
of an allocation function (17.6.3.4 [<A href="https://wg21.link/new.delete.placement">new.delete.placement</A>]) should be
treated similarly.</P>

<P><U>Possible resolution [SUPERSEDED]:</U></P>

<OL>
<LI>
<P>Change in 6.7.2 [<A href="https://wg21.link/intro.object#13">intro.object</A>] paragraph 13 as follows:</P>

<BLOCKQUOTE>

Any implicit or explicit invocation of a function named <TT>operator
new</TT> or <TT>operator new[]</TT> implicitly creates
objects <INS>with dynamic storage duration</INS> in the returned
region of storage and returns a pointer to a suitable created object.

</BLOCKQUOTE>

</LI>

<LI>
<P>Change in 6.7.5.1 [<A href="https://wg21.link/basic.stc.general#2">basic.stc.general</A>] paragraph 2 as follows:</P>

<BLOCKQUOTE>

Static, thread, and automatic storage durations are associated with
objects introduced by declarations (6.2 [<A href="https://wg21.link/basic.def">basic.def</A>]) and
implicitly created by the implementation
(6.7.7 [<A href="https://wg21.link/class.temporary">class.temporary</A>]). The dynamic storage duration is
associated with objects created <DEL>by a <I>new-expression</I>
(7.6.2.8 [<A href="https://wg21.link/expr.new">expr.new</A>])</DEL> <INS>in storage returned by an
allocation function (6.7.5.5.2 [<A href="https://wg21.link/basic.stc.dynamic.allocation">basic.stc.dynamic.allocation</A>]) other than a
non-allocating form (17.6.3.4 [<A href="https://wg21.link/new.delete.placement">new.delete.placement</A>]) or by C library
memory allocation (20.2.12 [<A href="https://wg21.link/c.malloc">c.malloc</A>])</INS>.

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 6.7.5.5.2 [<A href="https://wg21.link/basic.stc.dynamic.allocation#3">basic.stc.dynamic.allocation</A>] paragraph 3 as follows:</P>

<BLOCKQUOTE>

For an allocation function <DEL>other than a reserved placement
allocation function</DEL> <INS>other than a non-allocating form</INS>
(17.6.3.4 [<A href="https://wg21.link/new.delete.placement">new.delete.placement</A>]), the pointer returned on a successful
call shall represent the address of storage that is aligned as
follows:

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 6.7.5.6 [<A href="https://wg21.link/basic.stc.inherit#1">basic.stc.inherit</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

The storage duration of <DEL>subobjects and</DEL> reference members is
that of their complete object<INS>. The storage duration of an object
nested within another object <I>x</I> is the storage duration
of <I>x</I></INS> (6.7.2 [<A href="https://wg21.link/intro.object">intro.object</A>]).

</BLOCKQUOTE>

</LI>

<LI>
<P>Change in 7.6.2.8 [<A href="https://wg21.link/expr.new#9">expr.new</A>] paragraph 9 as follows:</P>

<BLOCKQUOTE>

<INS>An object created by a <I>new-expression</I> that invokes an
allocation function with a non-allocating form (see below) has the
storage duration of the object that used to occupy the region of
storage where the new object is created.</INS>

<DEL>Objects</DEL> <INS>Any other object</INS> created by
a <I>new-expression</I> <DEL>have</DEL> <INS>has</INS>
dynamic storage duration (6.7.5.5 [<A href="https://wg21.link/basic.stc.dynamic">basic.stc.dynamic</A>]).  [<I>Note
5:</I> The lifetime of such an object is not necessarily restricted to
the scope in which it is created. &#8212;<I>end note</I>]

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 20.2.12 [<A href="https://wg21.link/c.malloc#4">c.malloc</A>] paragraph 4 as follows:</P>

<BLOCKQUOTE>

These functions implicitly create objects (6.7.2 [<A href="https://wg21.link/intro.object">intro.object</A>])
<INS>with dynamic storage duration</INS> in the returned region of
storage and return a pointer to a suitable created object. In the case
of calloc and realloc, the objects are created before the storage is
zeroed or copied, respectively.

</BLOCKQUOTE>
</LI>
</OL>

<P><B>Additional note (December, 2023)</B></P>

<P>The approach outlined above is incomplete and the wrong direction.
The concept of storage duration determines when an object is created
and destroyed; for dynamic storage duration, the object is created and
destroyed by explicit program action.</P>

<P><B>Proposed resolution (approved by CWG 2024-01-19):</B></P>

<OL>
<LI>
<P>Change in 6.7.5.1 [<A href="https://wg21.link/basic.stc.general#2">basic.stc.general</A>] paragraph 2 as follows:</P>

<BLOCKQUOTE>

Static, thread, and automatic storage durations are associated with
objects introduced by declarations (6.2 [<A href="https://wg21.link/basic.def">basic.def</A>]) and
<DEL>implicitly created by the implementation</DEL> <INS>with
temporary objects</INS> (6.7.7 [<A href="https://wg21.link/class.temporary">class.temporary</A>]). The dynamic
storage duration is associated with objects created by
a <I>new-expression</I> (7.6.2.8 [<A href="https://wg21.link/expr.new">expr.new</A>]) <INS>or with
implicitly created objects (6.7.2 [<A href="https://wg21.link/intro.object">intro.object</A>])</INS>.

</BLOCKQUOTE>
</LI>
</OL>

<BR><BR><HR>
<A NAME="2546"></A><H4>2546.
  
Defaulted secondary comparison operators defined as deleted
</H4>
<B>Section: </B>11.10.4&#160; [<A href="https://wg21.link/class.compare.secondary">class.compare.secondary</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Jim X
 &#160;&#160;&#160;

 <B>Date: </B>2022-03-07


<P>(See also editorial issues
<A HREF="https://github.com/cplusplus/draft/issues/5335">5335</A> and
<A HREF="https://github.com/cplusplus/draft/issues/5336">5336</A>.)</P>

<P>Consider the example in 11.10.4 [<A href="https://wg21.link/class.compare.secondary#3">class.compare.secondary</A>] paragraph 3:</P>

<PRE>
  struct HasNoLessThan { };
  struct C {
    friend HasNoLessThan operator&lt;=&gt;(const C&amp;, const C&amp;);
    bool operator&lt;(const C&amp;) const = default;  //<SPAN CLASS="cmnt"> OK, function is deleted</SPAN>
  };
</PRE>

<P>While the comment may reflect the intent, it does not follow from
the wording.  11.10.4 [<A href="https://wg21.link/class.compare.secondary#2">class.compare.secondary</A>] paragraph 2 specifies:</P>

<BLOCKQUOTE>

The operator function with parameters <TT>x</TT> and <TT>y</TT> is
defined as deleted if

<UL>
<LI>
overload resolution (12.2 [<A href="https://wg21.link/over.match">over.match</A>]), as applied to <TT>x @
y</TT>, does not result in a usable candidate, or
</LI>

<LI>
the candidate selected by overload resolution is not a rewritten
candidate.
</LI>
</UL>

<P>Otherwise, the operator function yields <TT>x @ y</TT>. The defaulted
operator function is not considered as a candidate in the overload
resolution for the <TT>@</TT> operator.</P>

</BLOCKQUOTE>

<P>Overload resolution applied to <TT>x &lt; y</TT> results in a
usable candidate <TT>operator&lt;=&gt;</TT>
(12.2.1 [<A href="https://wg21.link/over.match.general">over.match.general</A>]) and that candidate is a rewritten
candidate (12.2.2.3 [<A href="https://wg21.link/over.match.oper#3.4">over.match.oper</A>] bullet 3.4),
thus <TT>operator&lt;</TT> in the above example is not deleted.
However, its definition is ill-formed, because the rewrite <TT>(x
&lt;=&gt; y) &lt; 0</TT> is ill-formed (12.2.2.3 [<A href="https://wg21.link/over.match.oper#8">over.match.oper</A>] paragraph 8).</P>

<P>There is implementation divergence.</P>

<P>Subclause 11.10.3 [<A href="https://wg21.link/class.spaceship#1">class.spaceship</A>] paragraph 1 seems to prefer an
ill-formed program for similar synthesized situations:</P>

<BLOCKQUOTE>

[<I>Note 1:</I> A synthesized three-way comparison is ill-formed if
overload resolution finds usable candidates that do not otherwise meet
the requirements implied by the defined expression. &#8212;<I>end
note</I>]

</BLOCKQUOTE>

<P><B>Proposed resolution (approved by CWG 2024-03-20):</B></P>

Change in 11.10.4 [<A href="https://wg21.link/class.compare.secondary#2">class.compare.secondary</A>] paragraph 2 as follows:

<BLOCKQUOTE>

The operator function with parameters <TT>x</TT> and <TT>y</TT> is
defined as deleted if

<UL>
<LI>
<INS>a first</INS> overload resolution (12.2 [<A href="https://wg21.link/over.match">over.match</A>]), as
applied to <TT>x @ y</TT>,

<UL>
<LI>does not result in a usable candidate, or</LI>
<LI>the <INS>selected</INS> candidate <DEL>selected by overload
resolution</DEL> is not a rewritten candidate<DEL>.</DEL> <INS>, or</INS>
</LI>
</UL>

</LI>

<LI class="ins">a second overload resolution for the expression
resulting from the interpretation of <TT>x @ y</TT> using the selected
rewritten candidate (12.2.2.3 [<A href="https://wg21.link/over.match.oper">over.match.oper</A>]) does not result in
a usable candidate (for example, that expression might be <TT>(x
&lt;=&gt; y) @ 0</TT>), or
</LI>

<LI class="ins">
<TT>x @ y</TT> cannot be implicitly converted to <TT>bool</TT>.
</LI>
</UL>

<P>
<INS>In any of the two overload resolutions above, the defaulted
operator function is not considered as a candidate for the <TT>@</TT>
operator.</INS> Otherwise, the operator function yields <TT>x @
y</TT>. <DEL>The defaulted operator function is not considered as a
candidate in the overload resolution for the <TT>@</TT>
operator.</DEL>
</P>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2547"></A><H4>2547.
  
Defaulted comparison operator function for non-classes
</H4>
<B>Section: </B>9.5.2&#160; [<A href="https://wg21.link/dcl.fct.def.default">dcl.fct.def.default</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Jim X
 &#160;&#160;&#160;

 <B>Date: </B>2022-03-07


<P>(See
<A HREF="https://github.com/cplusplus/draft/issues/5337">editorial issue 5337</A>.)</P>

<P>Subclause 9.5.2 [<A href="https://wg21.link/dcl.fct.def.default#1">dcl.fct.def.default</A>] paragraph 1 specifies:</P>

<BLOCKQUOTE>

A function definition whose <I>function-body</I> is of the form <TT>=
default ;</TT> is called an <I>explicitly-defaulted definition</I>.  A
function that is explicitly defaulted shall

<UL>

<LI>be a special member function or a comparison operator function
(12.4.3 [<A href="https://wg21.link/over.binary">over.binary</A>]), and
</LI>

<LI>
not have default arguments.
</LI>

</UL>

</BLOCKQUOTE>

<P>There seem to be no further restrictions on which comparison
operator functions are allowed to be defaulted.  For example,</P>

<PRE>
  enum E { };
  bool operator==(E, E) = default;  // <SPAN CLASS="cmnt">well-formed?</SPAN>
</PRE>

<P>Subclause 11.10.1 [<A href="https://wg21.link/class.compare.default#1">class.compare.default</A>] paragraph 1 applies only to comparison
operator functions "for some class":</P>

<BLOCKQUOTE>

A defaulted comparison operator function (12.4.3 [<A href="https://wg21.link/over.binary">over.binary</A>])
for some class <TT>C</TT> shall be a non-template function that is

<UL>

<LI>a non-static const non-volatile member of C having one parameter of type
<TT>const C&amp;</TT> and either no <I>ref-qualifier</I> or
the <I>ref-qualifier</I> &amp;, or
</LI>

<LI>a friend of <TT>C</TT> having either two parameters of
type <TT>const C&amp;</TT> or two parameters of type <TT>C</TT>.
</LI>

</UL>

</BLOCKQUOTE>

<P><B>Proposed resolution [SUPERSEDED]:</B></P>

<OL>

<LI>Change in 9.5.2 [<A href="https://wg21.link/dcl.fct.def.default#1">dcl.fct.def.default</A>] paragraph 1 as follows:

<BLOCKQUOTE>

A function definition whose <I>function-body</I> is of the form <TT>=
default ;</TT> is called an <I>explicitly-defaulted definition</I>.  A
function that is explicitly defaulted shall

<UL>
<LI>be a special member
function <INS>(11.4.4 [<A href="https://wg21.link/special">special</A>])</INS> or a comparison
operator function (12.4.3 [<A href="https://wg21.link/over.binary">over.binary</A>]<INS>,
11.10.1 [<A href="https://wg21.link/class.compare.default">class.compare.default</A>]</INS>), and
</LI>

<LI>
not have default arguments <INS>(9.3.4.7 [<A href="https://wg21.link/dcl.fct.default">dcl.fct.default</A>])</INS>.
</LI>
</UL>

</BLOCKQUOTE>
</LI>

<LI>Change in 11.10.1 [<A href="https://wg21.link/class.compare.default#1">class.compare.default</A>] paragraph 1 as follows:

<BLOCKQUOTE>

A defaulted comparison operator function (12.4.3 [<A href="https://wg21.link/over.binary">over.binary</A>])
<DEL>for some class <TT>C</TT></DEL> shall be a non-template function that is

<UL>

<LI>a non-static const non-volatile member of <INS>some
class</INS> <TT>C</TT> having one parameter of type
<TT>const C&amp;</TT> and either no <I>ref-qualifier</I> or
the <I>ref-qualifier</I> &amp;, or
</LI>

<LI>a friend of <INS>some class</INS> <TT>C</TT> having either two
parameters of type <TT>const C&amp;</TT> or two parameters of
type <TT>C</TT>.
</LI>

</UL>

<P>
<INS>Such a comparison operator function is termed a comparison
operator function for class <TT>C</TT>.</INS> A comparison operator
function for class <TT>C</TT> that is defaulted on its first
declaration ...</P>

</BLOCKQUOTE>

</LI>

</OL>

<P><B>CWG 2023-12-01</B></P>

<P>A defaulted comparison function for an incomplete class later
declared a friend for that class should be made ill-formed.</P>

<P><B>Proposed resolution (approved by CWG 2023-12-15):</B></P>

<OL>

<LI>Change in 9.5.2 [<A href="https://wg21.link/dcl.fct.def.default#1">dcl.fct.def.default</A>] paragraph 1 as follows:

<BLOCKQUOTE>

A function definition whose <I>function-body</I> is of the form <TT>=
default ;</TT> is called an <I>explicitly-defaulted definition</I>.  A
function that is explicitly defaulted shall

<UL>
<LI>be a special member
function <INS>(11.4.4 [<A href="https://wg21.link/special">special</A>])</INS> or a comparison
operator function (12.4.3 [<A href="https://wg21.link/over.binary">over.binary</A>]<INS>,
11.10.1 [<A href="https://wg21.link/class.compare.default">class.compare.default</A>]</INS>), and
</LI>

<LI>
not have default arguments <INS>(9.3.4.7 [<A href="https://wg21.link/dcl.fct.default">dcl.fct.default</A>])</INS>.
</LI>
</UL>

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 11.10.1 [<A href="https://wg21.link/class.compare.default#1">class.compare.default</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

A defaulted comparison operator function (12.4.3 [<A href="https://wg21.link/over.binary">over.binary</A>])
<DEL>for some class C</DEL> shall be a non-template function that <DEL>is</DEL>
<UL>
<LI>
<INS>is</INS> a non-static member or friend of <INS>some class</INS> C<INS>,</INS>
</LI>
<LI>
<INS>is defined as defaulted in <TT>C</TT> or in a context
where <TT>C</TT> is complete,</INS> and</LI>
<LI>either has two parameters of type const C&amp; or two parameters
of type C, where the implicit object parameter (if any) is considered
to be the first parameter.
</LI>
</UL>
<INS>Such a comparison operator function is termed a defaulted comparison
operator function for class <TT>C</TT>.</INS> Name lookups in the
implicit definition (9.5.2 [<A href="https://wg21.link/dcl.fct.def.default">dcl.fct.def.default</A>]) of a comparison
operator function are performed from a context equivalent to its
function-body.  A definition of a comparison operator as defaulted
that appears in a class shall be the first declaration of that
function. <INS>[ Example:</INS>

<PRE class="ins">
  struct S;
  bool operator==(S, S) = default;  // <SPAN CLASS="cmnt">error: </SPAN>S<SPAN CLASS="cmnt"> is not complete</SPAN>
  struct S {
    friend bool operator==(S, const S&amp;) = default; // <SPAN CLASS="cmnt">error: parameters of different types</SPAN>
  };
  enum E { };
  bool operator==(E, E) = default;  // <SPAN CLASS="cmnt">error: not a member or friend of a class</SPAN>
</PRE>

<INS>-- end example ]</INS>

</BLOCKQUOTE>

</LI>
</OL>

<BR><BR><HR>
<A NAME="2560"></A><H4>2560.
  
Parameter type determination in a <I>requirement-parameter-list</I>
</H4>
<B>Section: </B>7.5.7.1&#160; [<A href="https://wg21.link/expr.prim.req.general">expr.prim.req.general</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>2020-01-21




<P>Consider:</P>

<PRE>
  template&lt;typename T&gt;
    requires requires (T p[10]) { (decltype(p))nullptr; }
  int v = 42;
  auto r = v&lt;int&gt;; //<SPAN CLASS="cmnt"> well-formed? </SPAN>
</PRE>

<P>This example is only well-formed if the type of the
parameter <TT>p</TT> is adjusted to <TT>T*</TT>, but the provisions in
9.3.4.6 [<A href="https://wg21.link/dcl.fct#5">dcl.fct</A>] paragraph 5 cover function parameters
only.</P>

<P>One option is to specify application of the same adjustments as for
function parameters. Another option is to specify rules that arguably
are more useful in a <I>requires-expression</I>.</P>

<P><B>Proposed resolution (approved by CWG 2023-11-07):</B></P>

<P>Change in 7.5.7.1 [<A href="https://wg21.link/expr.prim.req.general#3">expr.prim.req.general</A>] paragraph 3 as follows:</P>

<BLOCKQUOTE>

A <I>requires-expression</I> may introduce local parameters using
a <I>parameter-declaration-clause</I>
<DEL>(9.3.4.6 [<A href="https://wg21.link/dcl.fct">dcl.fct</A>])</DEL>. A local parameter of
a <I>requires-expression</I> shall not have a default argument.
<INS>The type of such a parameter is determined as specified for
a function parameter in 9.3.4.6 [<A href="https://wg21.link/dcl.fct">dcl.fct</A>].</INS> These
parameters have no linkage, storage, or lifetime; they are only used
as notation for the purpose of defining
requirements. The <I>parameter-declaration-clause</I> of
a <I>requirement-parameter-list</I> shall not terminate with an
ellipsis.<br> [<I>Example 2:</I>
<PRE>
  template&lt;typename T&gt;
  concept C = requires(T t, ...) {  //<SPAN CLASS="cmnt"> error: terminates with an ellipsis</SPAN>
    t;
  };
<INS>  template&lt;typename T&gt;
  concept C2 = requires(T p[2]) {
    (decltype(p))nullptr;           //<SPAN CLASS="cmnt"> OK, </SPAN>p<SPAN CLASS="cmnt"> has type "pointer to </SPAN>T<SPAN CLASS="cmnt">"</SPAN>
  };</INS>
</PRE>
&#8212;<I>end example</I>]

</BLOCKQUOTE>

<P><B>CWG 2023-06-17</B></P>

<P>There are arguments in favor of both options.
Forwarded to EWG with
<A HREF="https://github.com/cplusplus/papers/issues/1582">paper issue 1582</A>.</P>

<P><B>EWG 2023-11-07</B></P>

<P>Accept the proposed resolution and forward to CWG for inclusion in C++26.</P>

<BR><BR><HR>
<A NAME="2568"></A><H4>2568.
  
Access checking during synthesis of defaulted comparison operator
</H4>
<B>Section: </B>11.10.1&#160; [<A href="https://wg21.link/class.compare.default">class.compare.default</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Nicolai Josuttis
 &#160;&#160;&#160;

 <B>Date: </B>2022-04-11




<P>Consider:</P>

<PRE>
  struct Base {
  protected:
    bool operator==(const Base&amp; other) const = default;
  };

  struct Child : Base {
    int i;
    bool operator==(const Child&amp; other) const = default;
  };
</PRE>

<P>Per 11.10.1 [<A href="https://wg21.link/class.compare.default#6">class.compare.default</A>] paragraph 6,</P>

<BLOCKQUOTE>

Let x<sub>i</sub> be an lvalue denoting the i-th element in the
expanded list of subobjects for an object x (of length n), where
x<sub>i</sub> is formed by a sequence of derived-to-base conversions
(12.2.4.2 [<A href="https://wg21.link/over.best.ics">over.best.ics</A>]), class member access expressions
(7.6.1.5 [<A href="https://wg21.link/expr.ref">expr.ref</A>]), and array subscript expressions
(7.6.1.2 [<A href="https://wg21.link/expr.sub">expr.sub</A>]) applied to x.

</BLOCKQUOTE>

<P>The derived-to-base conversion for <TT>this</TT> loses the context
of access to the protected <TT>Base::operator==</TT>, violating
11.8.5 [<A href="https://wg21.link/class.protected#1">class.protected</A>] paragraph 1. The example is rejected by
implementations, but ought to work.</P>

<P>For this related example, there is implementation divergence:</P>

<PRE>
  struct B {
  protected:
    constexpr operator int() const { return 0; }
  };
  struct D : B {
    constexpr bool operator==(const D&amp;) const = default;
  };
  template&lt;typename T&gt; constexpr auto comparable(T t) -&gt; decltype(t == t) { return t == t; }
  constexpr bool comparable(...) { return false; }
  static_assert(comparable(D{}));
</PRE>

<P>Is <TT>D::operator==</TT> deleted, because its defaulted definition
violates the protected access rules?  Is <TT>D::operator==</TT> not
deleted, but synthesis fails on use because of the proctected access
rules?  Is the synthesis not in the immediate context, making the
expression <TT>comparable(D{})</TT> ill-formed?</P>

<P><B>CWG 2023-06-17</B></P>

<P>There is no implementation divergence; the first example is
intended to be well-formed.</P>

<P><B>Proposed resolution (approved by CWG 2023-12-01):</B></P>

<P>Change in 11.10.1 [<A href="https://wg21.link/class.compare.default#1">class.compare.default</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

... Name lookups <INS>and access checks</INS> in the implicit
definition (9.5.2 [<A href="https://wg21.link/dcl.fct.def.default">dcl.fct.def.default</A>]) of a comparison operator
function are performed from a context equivalent to
its <I>function-body</I> . A definition of a comparison operator as
defaulted that appears in a class shall be the first declaration of
that function.

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2634"></A><H4>2634.
  
Avoid circularity in specification of scope for friend class declarations
</H4>
<B>Section: </B>9.2.9.5&#160; [<A href="https://wg21.link/dcl.type.elab">dcl.type.elab</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Jim X
 &#160;&#160;&#160;

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


<P>Consider:</P>

<PRE>
auto f(struct X* ptr) {
  struct D {
    private:
      int d;
      friend class X;      //<SPAN CLASS="cmnt"> #1</SPAN>
  };
  return D{};
}
X* b = 0;
struct X {
  void show() {
    auto t = f(0);
    t.d = 10;              //<SPAN CLASS="cmnt"> #2 error: </SPAN>::X<SPAN CLASS="cmnt"> is not a friend of </SPAN>f::D
  }
};
</PRE>

<P>The target scope for #2 is <TT>f</TT>'s block scope,
making <TT>::X</TT> not a friend of <TT>f::D</TT>.  Thus the access at
#2 is ill-formed. Clang disagrees.</P>

<P>Subclause 9.2.9.5 [<A href="https://wg21.link/dcl.type.elab#3">dcl.type.elab</A>] paragraph 3 specifies:</P>

<BLOCKQUOTE>

<P>
... If E contains an identifier but
no <I>nested-name-specifier</I> and (unqualified) lookup for the
identifier finds nothing, E shall not be introduced by the enum
keyword and declares the identifier as a <I>class-name</I>. The target
scope of E is the nearest enclosing namespace or block scope.
</P>

<P>If an <I>elaborated-type-specifier</I> appears with the friend
specifier as an entire <I>member-declaration</I>, the
<I>member-declaration</I> shall have one of the following forms:

<pre>
friend <I>class-key</I> <I>nested-name-specifier<sub>opt</sub></I> identifier ;
...
</pre>
Any unqualified lookup for the <I>identifier</I> (in the first case)
does not consider scopes that contain the target scope; no name is
bound.</P>

</BLOCKQUOTE>

<P>This specification is circular in that the target scope that limits
unqualified lookup is defined only if the <I>identifier</I> is
actually declared, but the <I>identifier</I> is declared only if
lookup finds nothing.</P>

<P><B>Proposed resolution (approved by CWG 2023-11-11):</B></P>

<P>Change in 9.2.9.5 [<A href="https://wg21.link/dcl.type.elab#4">dcl.type.elab</A>] paragraph 4 as follows:</P>

<BLOCKQUOTE>

... Any unqualified lookup for the <I>identifier</I> (in the first
case) does not consider scopes that contain the
<DEL>target</DEL> <INS>nearest enclosing namespace or block </INS>
scope; no name is bound. [ Note: ... ]

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2637"></A><H4>2637.
  
Injected-class-name as a <I>simple-template-id</I>
</H4>
<B>Section: </B>11.1&#160; [<A href="https://wg21.link/class.pre">class.pre</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Shafik Yaghmour
 &#160;&#160;&#160;

 <B>Date: </B>2022-10-26




<P>Issue 2237 sought to
disallow <I>simple-template-id</I>s as constructor names, by referring
to the injected-class-name.  However, 11.1 [<A href="https://wg21.link/class.pre#2">class.pre</A>] paragraph 2 specifies:</P>

<BLOCKQUOTE>

The <I>class-name</I> is also bound in the scope of the class
(template) itself; this is known as the <I>injected-class-name</I>.

</BLOCKQUOTE>

<P>The grammar non-terminal <I>class-name</I> includes the option of
a <I>simple-template-id</I> (for declaring a partial
specialization).</P>

<P><B>Proposed resolution (approved by CWG 2023-11-11):</B></P>

<P>Change in 11.1 [<A href="https://wg21.link/class.pre#2">class.pre</A>] paragraph 2 as follows:</P>

<BLOCKQUOTE>

The <INS>component name of the</INS> <I>class-name</I> is also bound in
the scope of the class (template) itself; this is known as
the <I>injected-class-name</I>. ...

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2638"></A><H4>2638.
  
Improve the example for initializing by initializer list
</H4>
<B>Section: </B>9.4.5&#160; [<A href="https://wg21.link/dcl.init.list">dcl.init.list</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Shafik Yaghmour
 &#160;&#160;&#160;

 <B>Date: </B>2022-10-26


<P>Issue 2137 amended the rules for
initialization by initializer list, but neglected to add an
example.</P>

<P><B>Proposed resolution (approved by CWG 2023-11-11):</B></P>

<P>Change the example in 9.4.5 [<A href="https://wg21.link/dcl.init.list#3.7">dcl.init.list</A>] bullet 3.7 as follows:</P>

<PRE>
struct S {
  S(std::initializer_list&lt;double&gt;); //<SPAN CLASS="cmnt"> #1</SPAN>
  S(std::initializer_list&lt;int&gt;);    //<SPAN CLASS="cmnt"> #2</SPAN>
  <INS>S(std::initializer_list&lt;S&gt;);      //<SPAN CLASS="cmnt"> #3</SPAN></INS>
  S();                              //<SPAN CLASS="cmnt"> <DEL>#3</DEL><INS>#4</INS></SPAN>

  //<SPAN CLASS="cmnt"> ...</SPAN>
};
S s1 = { 1.0, 2.0, 3.0 };  //<SPAN CLASS="cmnt"> invoke #1</SPAN>
S s2 = { 1, 2, 3 };        //<SPAN CLASS="cmnt"> invoke #2</SPAN>
<INS>S s3{s2};                  //<SPAN CLASS="cmnt"> invoke #3 (not the copy constructor)</SPAN></INS>
S <DEL>s3</DEL><INS>s4</INS> = { };              //<SPAN CLASS="cmnt"> invoke <DEL>#3</DEL><INS>#4</INS></SPAN>
</PRE>

<BR><BR><HR>
<A NAME="2657"></A><H4>2657.
  
Cv-qualification adjustment when binding reference to temporary
</H4>
<B>Section: </B>9.4.4&#160; [<A href="https://wg21.link/dcl.init.ref">dcl.init.ref</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Brian Bi
 &#160;&#160;&#160;

 <B>Date: </B>2022-11-10


<P>Core issue 2481 was resolved by
clarifying that the temporary object in p5.4.2 is cv-qualified if the
reference being initialized is cv-qualified. However, this is not the
right bullet point for the example given,</P>

<PRE>
  constexpr const int &amp;r = 42;
</PRE>

<P>Such an initialization would actually use bullet 5.3.1
instead. (5.4.2 would be used if the initializer were, for example,
3.14.) We therefore need to make a similar clarification in bullet
5.3, and ideally using the same language.</P>

<P><B>Proposed resolution (approved by CWG 2024-03-20):</B></P>

<OL>
<LI>
<P>Change in 9.4.4 [<A href="https://wg21.link/dcl.init.ref#5.3">dcl.init.ref</A>] bullet 5.3 as follows:</P>

<BLOCKQUOTE>

Otherwise, if the initializer expression
<UL>
<LI>is an rvalue (but
not a bit-field) or function lvalue and &#8220;cv1 T1&#8221; is
reference-compatible with &#8220;cv2 T2&#8221;, or</LI>
<LI>has a
class type (i.e., T2 is a class type), where T1 is not
reference-related to T2, and can be converted to an rvalue or function
lvalue of type &#8220;cv3 T3&#8221;, where &#8220;cv1 T1&#8221; is
reference-compatible with &#8220;cv3 T3&#8221; (see
12.2.2.7 [<A href="https://wg21.link/over.match.ref">over.match.ref</A>]),</LI>
</UL>
then the initializer expression in the
first case and the converted expression in the second case is called
the converted initializer. If the converted initializer is a prvalue,
<INS>let</INS> its type <INS>be denoted by</INS> <TT>T4</TT><INS>; the
temporary materialization conversion (7.3.5 [<A href="https://wg21.link/conv.rval">conv.rval</A>]) is
applied, considering the type of the prvalue to be</INS> <DEL>is
adjusted to type</DEL> &#8220;cv1 T4&#8221;
(7.3.6 [<A href="https://wg21.link/conv.qual">conv.qual</A>]) <DEL>and the temporary materialization
conversion (7.3.5 [<A href="https://wg21.link/conv.rval">conv.rval</A>]) is applied</DEL>. In any case, the
reference binds to the resulting glvalue (or to an appropriate base
class subobject).

</BLOCKQUOTE>
</LI>

<LI>
<P>Append to the example in 9.4.4 [<A href="https://wg21.link/dcl.init.ref#5.3">dcl.init.ref</A>] bullet 5.3 as follows:</P>

<PRE>
  B&amp;&amp; rrb = x;  //<SPAN CLASS="cmnt"> binds directly to the result of</SPAN> operator B

  <INS>constexpr int f() {
    const int &amp;x = 42;
    const_cast&lt;int &amp;&gt;(x) = 1;  // <SPAN CLASS="cmnt">undefined behavior</SPAN>
    return x;
  }
  constexpr int z = f();   // <SPAN CLASS="cmnt">error: not a constant expression</SPAN></INS>
</PRE>

</LI>

<LI>

<P>Change the example in 9.4.4 [<A href="https://wg21.link/dcl.init.ref#5.4">dcl.init.ref</A>] bullet 5.4 as follows:</P>

<PRE>
  const double&amp; rcd2 = 2;   //<SPAN CLASS="cmnt"> rcd2 refers to temporary with <INS>type</INS> </SPAN><INS>const double</INS><SPAN CLASS="cmnt"> <INS>and</INS> value 2.0</SPAN>
</PRE>

</LI>

</OL>

<BR><BR><HR>
<A NAME="2661"></A><H4>2661.
  
Missing disambiguation rule for <I>pure-specifier</I> vs. <I>brace-or-equal-initializer</I>
</H4>
<B>Section: </B>11.4.1&#160; [<A href="https://wg21.link/class.mem.general">class.mem.general</A>]
 &#160;&#160;&#160;

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

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

 <B>Date: </B>2022-10-07


<P>Subclause 11.4.1 [<A href="https://wg21.link/class.mem.general">class.mem.general</A>] has this grammar:</P>

<PRE>
    <I>member-declarator:
        declarator virt-specifier-seq[opt] pure-specifier[opt]
        declarator brace-or-equal-initializer[opt]

    pure-specifier:</I>
        = 0
</PRE>

<P>The primary issue is that <TT>foo = 0</TT> matches
both <I>member-declarator</I> productions. Secondarily,
a <I>declarator</I> by itself is also ambiguous.</P>

<P>Code such as <TT>virtual FunctionType f = 0;</TT> can be valid, so
disambiguation on the syntactic form of the <I>declarator</I> is not
possible.</P>

<P><B>Proposed resolution (approved by CWG 2024-02-16):</B></P>

<P>Change and add before 11.4.1 [<A href="https://wg21.link/class.mem.general#1">class.mem.general</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>
<PRE>
    <I>member-declarator:
        declarator virt-specifier-seq<SUB>opt</SUB> pure-specifier<SUB>opt</SUB>
        declarator brace-or-equal-initializer<DEL><SUB>opt</SUB></DEL></I>
</PRE>
</BLOCKQUOTE>

<BLOCKQUOTE class="ins">
In the absence of a <I>virt-specifier-seq</I>, the token sequence <TT>= 0</TT> is treated as a <I>pure-specifier</I> if the type of
the <I>declarator-id</I> (9.3.4.1 [<A href="https://wg21.link/dcl.meaning.general">dcl.meaning.general</A>]) is a function type, and is
otherwise treated as a <I>brace-or-equal-initializer</I>. [ <I>Note:</I> If the
member declaration acquires a function type through template
instantiation, the program is ill-formed; see 13.9.1 [<A href="https://wg21.link/temp.spec.general">temp.spec.general</A>]. <I>--end note</I> ]
</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2668"></A><H4>2668.
  
<TT>co_await</TT> in a <I>lambda-expression</I>
</H4>
<B>Section: </B>7.6.2.4&#160; [<A href="https://wg21.link/expr.await">expr.await</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Jim X
 &#160;&#160;&#160;

 <B>Date: </B>2022-12-12


<P>Subclause 7.6.2.4 [<A href="https://wg21.link/expr.await#2">expr.await</A>] paragraph 2 disallows
an <I>await-expression</I> to appear in the body of
a <I>lambda-expression</I>:</P>

<BLOCKQUOTE>

An <I>await-expression</I> shall appear only in a
potentially-evaluated expression within the <I>compound-statement</I>
of a <I>function-body</I> outside of a handler
(14.1 [<A href="https://wg21.link/except.pre">except.pre</A>]). ...

</BLOCKQUOTE>

<P>This is probably unintended.</P>

<P><B>Proposed resolution (approved by CWG 2023-11-11):</B></P>

<P>Change in 7.6.2.4 [<A href="https://wg21.link/expr.await#2">expr.await</A>] paragraph 2 as follows:</P>

<BLOCKQUOTE>

An <I>await-expression</I> shall appear
only <DEL>in</DEL> <INS>as</INS> a potentially-evaluated expression
within the <I>compound-statement</I> of
a <I>function-body</I> <INS>or <I>lambda-expression</I>, in either
case</INS> outside of a handler (14.1 [<A href="https://wg21.link/except.pre">except.pre</A>]). ...

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2689"></A><H4>2689.
  
Are cv-qualified <TT>std::nullptr_t</TT> fundamental types?
</H4>
<B>Section: </B>6.8.2&#160; [<A href="https://wg21.link/basic.fundamental">basic.fundamental</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Anoop Rana
 &#160;&#160;&#160;

 <B>Date: </B>2022-12-08


<P>It is unclear whether <I>cv</I> <TT>std::nullptr_t</TT> is a
fundamental type, given that it is declared in a library header and
cv-qualifications are not mentioned in
6.8.2 [<A href="https://wg21.link/basic.fundamental#15">basic.fundamental</A>] paragraph 15.</P>

<P><B>Proposed resolution (approved by CWG 2023-12-01):</B></P>

<P>Change in 6.8.2 [<A href="https://wg21.link/basic.fundamental#15">basic.fundamental</A>] paragraph 15 as follows:</P>

<BLOCKQUOTE>

<INS>The types denoted by <I>cv</I> <TT>std::nullptr_t</TT> are
distinct types.</INS> A value of type <TT>std::nullptr_t</TT> is a
null pointer constant (7.3.12 [<A href="https://wg21.link/conv.ptr">conv.ptr</A>]). Such values
participate in the pointer and the pointer-to-member conversions
(7.3.12 [<A href="https://wg21.link/conv.ptr">conv.ptr</A>],
7.3.13 [<A href="https://wg21.link/conv.mem">conv.mem</A>]).  <TT>sizeof(std::nullptr_t)</TT> shall
be equal to <TT>sizeof(void*)</TT>.

<P>The types described in this subclause are called <I>fundamental
types</I>.  [<I>Note 11:</I> Even if the implementation defines two or
more fundamental types to have the same value representation, they are
nevertheless different types. &#8212;<I>end note</I>]</P>

</BLOCKQUOTE>


<BR><BR><HR>
<A NAME="2700"></A><H4>2700.
  
<TT>#error</TT> disallows existing implementation practice
</H4>
<B>Section: </B>4.1.1&#160; [<A href="https://wg21.link/intro.compliance.general">intro.compliance.general</A>]
 &#160;&#160;&#160;

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

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

 <B>Date: </B>2023-02-13




<P>The resolution for issue 2518 disallows
existing implementation practice, as detailed below:</P>

<UL>
<LI>The requirement to issue a diagnostic message for each appearance
of <TT>#warning</TT> conflicts with existing implementations having a
diagnostic limit.  Furthermore, an implementation with an on-the-fly
incremental preprocessor is no longer allowed to abort the compilation
when an error deemed fatal happens (e.g. a <TT>#include</TT> file that
does not exist).</LI>

<LI>The wording does not allow for implementation-specific mechanisms
for creating a preprocessing translation unit, such as vendor-specific
forms of <TT>#if</TT>-like directives and <TT>#pragma once</TT>.</LI>

</UL>

<P><U>Suggested resolution [SUPERSEDED]:</U></P>

<OL>

<LI>
<P>Change in 4.1.1 [<A href="https://wg21.link/intro.compliance.general#2">intro.compliance.general</A>] paragraph 2 as follows:</P>

<BLOCKQUOTE>

Furthermore, a conforming implementation
<UL>
<LI>shall not accept a preprocessing translation unit containing a
#error preprocessing directive
(15.8 [<A href="https://wg21.link/cpp.error">cpp.error</A>])<DEL>,</DEL> <INS>and</INS>
</LI>

<LI><DEL>shall issue at least one diagnostic message for each #warning or
#error preprocessing directive not following a #error preprocessing
directive in a preprocessing translation unit, and</DEL></LI>

<LI>shall not accept a translation unit with
a <I><TT>static_assert</TT>-declaration</I> that fails
(9.1 [<A href="https://wg21.link/dcl.pre">dcl.pre</A>]).</LI>
</UL>

</BLOCKQUOTE>

</LI>

<LI>
<P>Change in 5.1 [<A href="https://wg21.link/lex.separate#1">lex.separate</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

The text of the program is kept in units called source files in this
document. A source file together with all the headers
(16.4.2.3 [<A href="https://wg21.link/headers">headers</A>]) and source files included
(15.3 [<A href="https://wg21.link/cpp.include">cpp.include</A>]) via the preprocessing directive #include,
less any source lines skipped by any of the conditional inclusion
(15.2 [<A href="https://wg21.link/cpp.cond">cpp.cond</A>]) preprocessing directives <INS>or by the
implementation-defined behavior of
any <I>conditionally-supported-directive</I>s
(15.1 [<A href="https://wg21.link/cpp.pre">cpp.pre</A>])</INS>, is called a <I>preprocessing
translation unit</I>.

</BLOCKQUOTE>
</LI>

</OL>

<P><B>CWG 2023-03-03</B></P>

<P>Permit that <TT>#warning</TT> can be ignored if another diagnostic
is produced.</P>

<P><B>Proposed resolution (approved by CWG 2024-01-19):</B></P>

<OL>
<LI>
<P>Change in 4.1.1 [<A href="https://wg21.link/intro.compliance.general#2.3">intro.compliance.general</A>] bullet 2.3 as follows:</P>

<BLOCKQUOTE>

<UL>
<LI>...</LI>

<LI>Otherwise, if a program contains

<UL>
<LI>a violation of any diagnosable rule<DEL> or</DEL><INS>,</INS>
</LI>

<LI><INS>a preprocessing translation unit with a <TT>#warning</TT>
preprocessing directive (15.8 [<A href="https://wg21.link/cpp.error">cpp.error</A>]), or</INS></LI>

<LI>an occurrence of a construct described in this document as
&#8220;conditionally-supported&#8221; when the implementation does not
support that construct,</LI>
</UL>
a conforming implementation shall issue at least one diagnostic message.</LI>
</UL>

</BLOCKQUOTE>

</LI>

<LI>
<P>Change in 4.1.1 [<A href="https://wg21.link/intro.compliance.general#2">intro.compliance.general</A>] paragraph 2 as follows:</P>

<BLOCKQUOTE>

Furthermore, a conforming implementation shall not accept
<UL>
<LI>a preprocessing translation unit containing a
#error preprocessing directive
(15.8 [<A href="https://wg21.link/cpp.error">cpp.error</A>])<DEL>,</DEL> <INS>or</INS>
</LI>

<LI><DEL>shall issue at least one diagnostic message for each #warning or
#error preprocessing directive not following a #error preprocessing
directive in a preprocessing translation unit, and</DEL></LI>

<LI>
<DEL>shall not accept</DEL> a translation unit with
a <I><TT>static_assert</TT>-declaration</I> that fails
(9.1 [<A href="https://wg21.link/dcl.pre">dcl.pre</A>]).</LI>
</UL>

</BLOCKQUOTE>

</LI>

<LI>
<P>Change in 5.1 [<A href="https://wg21.link/lex.separate#1">lex.separate</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

The text of the program is kept in units called source files in this
document. A source file together with all the headers
(16.4.2.3 [<A href="https://wg21.link/headers">headers</A>]) and source files included
(15.3 [<A href="https://wg21.link/cpp.include">cpp.include</A>]) via the preprocessing directive #include,
less any source lines skipped by any of the conditional inclusion
(15.2 [<A href="https://wg21.link/cpp.cond">cpp.cond</A>]) preprocessing directives,
<INS>as modified by the implementation-defined behavior of any
conditionally-supported-directives (15.1 [<A href="https://wg21.link/cpp.pre">cpp.pre</A>]) and
pragmas (15.9 [<A href="https://wg21.link/cpp.pragma">cpp.pragma</A>]), if any,</INS>
is called a <I>preprocessing translation unit</I>.

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 15.8 [<A href="https://wg21.link/cpp.error">cpp.error</A>] as follows:</P>


<BLOCKQUOTE>

A preprocessing directive of <DEL>either of the following
forms</DEL> <INS>the form</INS>

<PRE>
# error <I>pp-tokens<SUB>opt</SUB> new-line</I>
</PRE>

<INS>renders the program ill-formed.  A preprocessing directive of the
form</INS>
<PRE>
# warning <I>pp-tokens<SUB>opt</SUB> new-line</I>
</PRE>
<DEL>causes</DEL> <INS>requires</INS> the implementation to
produce <DEL>a</DEL> <INS>at least one</INS> diagnostic
message <INS>for the preprocessing translation unit
(4.1.1 [<A href="https://wg21.link/intro.compliance.general">intro.compliance.general</A>])</INS> <DEL>that</DEL>.

<P>
<INS><I>Recommended practice:</I> Any diagnostic message caused by
either of these directives</INS> should include the specified sequence
of preprocessing tokens<DEL>; the <TT>#error</TT> directive renders
the program ill-formed</DEL>.</P>

</BLOCKQUOTE>
</LI>

</OL>

<BR><BR><HR>
<A NAME="2707"></A><H4>2707.
  
Deduction guides cannot have a trailing <I>requires-clause</I>
</H4>
<B>Section: </B>13.7.2.3&#160; [<A href="https://wg21.link/temp.deduct.guide">temp.deduct.guide</A>]
 &#160;&#160;&#160;

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

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

 <B>Date: </B>2020-02-26




<P>The grammar for <I>deduction-guide</I> does not, but should, allow
a trailing <I>requires-clause</I>:</P>

<BLOCKQUOTE>

<PRE>
<I>deduction-guide</I>:
   <I>explicit-specifier<sub>opt</sub> template-name</I> ( <I>parameter-declaration-clause</I> ) -&gt; <I>simple-template-id</I> ;
</PRE>

</BLOCKQUOTE>

<P><B>Proposed resolution (approved by CWG 2023-11-11):</B></P>

<P>Change the grammar in 13.7.2.3 [<A href="https://wg21.link/temp.deduct.guide#1">temp.deduct.guide</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

<PRE>
<I>deduction-guide</I>:
   <I>explicit-specifier<SUB>opt</SUB> template-name</I> ( <I>parameter-declaration-clause</I> ) <INS><I>requires-clause<SUB>opt</SUB></I></INS> -&gt; <I>simple-template-id</I> ;
</PRE>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2714"></A><H4>2714.
  
Implicit deduction guides omit properties from the parameter-declaration-clause of a constructor
</H4>
<B>Section: </B>12.2.2.9&#160; [<A href="https://wg21.link/over.match.class.deduct">over.match.class.deduct</A>]
 &#160;&#160;&#160;

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

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

 <B>Date: </B>2017-02-13




<P>Subclause 12.2.2.9 [<A href="https://wg21.link/over.match.class.deduct#1.1.2">over.match.class.deduct</A>] bullet 1.1.2 specifies:</P>

<BLOCKQUOTE>

<UL>
<LI>The types of the function parameters are those of the constructor.
</LI>
</UL>

</BLOCKQUOTE>

<P>However, this does not consider default arguments or variadic
constructors.</P>

<P><B>Proposed resolution (approved by CWG 2023-04-28):</B></P>

<P>(This also resolves issue 2628.)</P>

<P>Change in 12.2.2.9 [<A href="https://wg21.link/over.match.class.deduct#1">over.match.class.deduct</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

<UL>
<LI>If C is defined, for each constructor of C, a function template with
the following properties:
<UL>
<LI>The template parameters are the
template parameters of C followed by the template parameters
(including default template arguments) of the constructor, if any.
</LI>
<LI>
<INS>The associated constraints (13.5.3 [<A href="https://wg21.link/temp.constr.decl">temp.constr.decl</A>]) are
the conjunction of the associated constraints of <TT>C</TT> and the associated
constraints of the constructor, if any. [ Note: A
<I>constraint-expression</I> in the <I>template-head</I> of <TT>C</TT>
is checked for satisfaction before any constraints from the
<I>template-head</I> or <I>trailing-requires-clause</I> of the
constructor. -- end note ]</INS>
</LI>
<LI>The <DEL>types of the function parameters are those</DEL>
<INS><I>parameter-declaration-clause</I> is that</INS> of the
constructor.
</LI>
<LI>The return type is the class template
specialization designated by C and template arguments corresponding to
the template parameters of C.
</LI>
</UL>
</LI>
<LI>If C is not defined or does not
declare any constructors, an additional function template derived as
above from a hypothetical constructor C().</LI>
<LI>An additional
function template derived as above from a hypothetical constructor
C(C), called the copy deduction candidate.</LI>
<LI>For each <I>deduction-guide</I>, a function or function template
with the following properties:
<UL>
<LI>The <DEL>template
parameters</DEL> <INS><I>template-head</I></INS>, if any, and
<DEL>function parameters</DEL>
<INS><I>parameter-declaration-clause</I></INS> are those of
the <I>deduction-guide</I>.
</LI>
<LI>The return type is the <I>simple-template-id</I> of
the <I>deduction-guide</I>.
</LI>
</UL>
</LI>
</UL>
</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2745"></A><H4>2745.
  
Dependent odr-use in generic lambdas
</H4>
<B>Section: </B>6.3&#160; [<A href="https://wg21.link/basic.def.odr">basic.def.odr</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Shafik Yaghmour
 &#160;&#160;&#160;

 <B>Date: </B>2022-12-13




<P>Default template arguments of generic lambdas can refer to local
variables.  It is unclear whether the potential odr-use is checked
when parsing the template definition or when instantiating the
template.</P>

<P>There is wide implementation divergence.</P>

<P><B>Proposed resolution (approved by CWG 2024-03-20):</B></P>

<P>Insert a new paragraph before 6.3 [<A href="https://wg21.link/basic.def.odr#11">basic.def.odr</A>] paragraph 11:</P>

<BLOCKQUOTE>

<P class="ins">
[ Example:
</P>
<PRE class="ins">
  void g() {
    constexpr int x = 1;
    auto lambda = [] &lt;typename T, int = ((T)x, 0)&gt; {};  //<SPAN CLASS="cmnt"> OK</SPAN>
    lambda.operator()&lt;int, 1&gt;();         //<SPAN CLASS="cmnt"> OK, does not consider x at all</SPAN>
    lambda.operator()&lt;int&gt;();            //<SPAN CLASS="cmnt"> OK, does not odr-use </SPAN>x
    lambda.operator()&lt;const int&amp;&gt;();     //<SPAN CLASS="cmnt"> error: odr-uses x from a context where x is not odr-usable</SPAN>
  }

  void h() {
    constexpr int x = 1;
    auto lambda = [] &lt;typename T&gt; { (T)x; };  //<SPAN CLASS="cmnt"> OK</SPAN>
    lambda.operator()&lt;int&gt;();            //<SPAN CLASS="cmnt"> OK, does not odr-use </SPAN>x
    lambda.operator()&lt;void&gt;();           //<SPAN CLASS="cmnt"> OK, does not odr-use </SPAN>x
    lambda.operator()&lt;const int&amp;&gt;();     //<SPAN CLASS="cmnt"> error: odr-uses x from a context where x is not odr-usable</SPAN>
  }
</PRE>
<P class="ins">
-- end example ]
</P>

<P>
Every program shall contain at least one definition of every function
or variable ...
</P>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2746"></A><H4>2746.
  
Checking of default template arguments
</H4>
<B>Section: </B>13.8.1&#160; [<A href="https://wg21.link/temp.res.general">temp.res.general</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Shafik Yaghmour
 &#160;&#160;&#160;

 <B>Date: </B>2022-12-13




<P>Consider:</P>

<PRE>
  static int x = 1;
  template&lt;auto y = x&gt; void f() {}
</PRE>

<P>Is the definition of <TT>f</TT> well-formed? Since <TT>x</TT> is
not a constant expression, any use of the default template argument is
ill-formed, but for example <TT>f&lt;5&gt;()</TT> does not actually
use it.</P>

<P>Are implementations allowed or required to reject this situation,
even if the template is never instantiated?  If the default template
argument is dependent, checking may need to be deferred to
instantiations in any case.</P>

<P><B>Proposed resolution (approved by CWG 2024-03-01):</B></P>

<P>Change in 13.8.1 [<A href="https://wg21.link/temp.res.general#6">temp.res.general</A>] paragraph 6 as follows:</P>

<BLOCKQUOTE>

<P>The validity of a template may be checked prior to any instantiation.
[<I>Note :</I> ... &#8212;<I>end note</I>]</P>

<P>The program is ill-formed, no diagnostic required, if:</P>

<UL>
<LI>no valid specialization, ignoring
<I>static_assert-declaration</I>s that fail, can be generated for a
template or a substatement of a constexpr if statement
(8.5.2 [<A href="https://wg21.link/stmt.if">stmt.if</A>]) within a template and the template is not
instantiated, or</LI>

<LI class="ins">
no valid specialization, ignoring
<I>static_assert-declaration</I>s that fail, can be generated for
a default <I>template-argument</I> and the
default <I>template-argument</I> is not used in any instantiation, or
</LI>

<LI>any <I>constraint-expression</I> in the program, introduced or
otherwise, has (in its normal form) an atomic constraint A where no
satisfaction check of A could be well-formed and no satisfaction check
of A is performed, or</LI>

<LI>every valid specialization of a variadic template requires an
empty template parameter pack, or</LI>

<LI>a hypothetical instantiation of a template immediately following
its definition would be ill-formed due to a construct that does not
depend on a template parameter, or</LI>

<LI>the interpretation of such a construct in the hypothetical
instantiation is different from the interpretation of the
corresponding construct in any actual instantiation of the
template.</LI>
</UL>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2748"></A><H4>2748.
  
Accessing static data members via null pointer
</H4>
<B>Section: </B>7.6.1.5&#160; [<A href="https://wg21.link/expr.ref">expr.ref</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Tomasz Kami&#324;ski
 &#160;&#160;&#160;

 <B>Date: </B>2023-06-13


<P>Consider:</P>

<PRE>
  struct C { static int foo; };
  C* c = nullptr;
</PRE>

<P>The behavior of <TT>(*c).foo</TT> is clearly undefined per
7.6.1.5 [<A href="https://wg21.link/expr.ref#1">expr.ref</A>] paragraph 1:</P>

<BLOCKQUOTE>

The postfix expression before the dot or arrow is evaluated ...

</BLOCKQUOTE>

<P>However, the treatment of <TT>c-&gt;foo</TT> is less clear, because
the transformation to the form <TT>(*(E1)).E2</TT> occurs later.</P>

<P><B>Proposed resolution (approved by CWG 2023-12-15):</B></P>

<P>Move a part of 7.6.1.5 [<A href="https://wg21.link/expr.ref#1">expr.ref</A>] paragraph 1 to before paragraph 3
and edit as follows:</P>

<BLOCKQUOTE>

<P>A postfix expression followed by a dot . or an arrow -&gt;, optionally
followed by the keyword template, and then followed by
an <I>id-expression</I>, is a postfix expression. <DEL>The postfix
expression before the dot or arrow is evaluated; [ Footnote: ... ] the
result of that evaluation, together with the <I>id-expression</I>,
determines the result of the entire postfix expression.</DEL>  [<I>Note
1:</I> If the keyword template is used, the following unqualified name
is considered to refer to a template (13.3 [<A href="https://wg21.link/temp.names">temp.names</A>]).  If
a <I>simple-template-id</I> results and is followed by a ::,
the <I>id-expression</I> is a <I>qualified-id</I>. &#8212;<I>end
note</I>]
</P>

<P>For the first option (dot) the first expression shall be a
glvalue. For the second option (arrow) the first expression shall be a
prvalue having pointer type. The expression E1-&gt;E2 is converted to
the equivalent form (*(E1)).E2; the remainder of
7.6.1.5 [<A href="https://wg21.link/expr.ref">expr.ref</A>] will address only the first option
(dot). [ Footnote: ... ]
</P>

<P class="ins">
The postfix
expression before the dot is evaluated; [ Footnote: ... ] the
result of that evaluation, together with the <I>id-expression</I>,
determines the result of the entire postfix expression.
</P>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2771"></A><H4>2771.
  
Transformation for <I>unqualified-id</I>s in address operator
</H4>
<B>Section: </B>11.4.3&#160; [<A href="https://wg21.link/class.mfct.non.static">class.mfct.non.static</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Jim X
 &#160;&#160;&#160;

 <B>Date: </B>2023-07-16


<P>Consider:</P>

<PRE>
  struct A{
    int a;
    void show(){
      int* r = &amp;a; //<SPAN CLASS="cmnt"> #1 </SPAN>
    }
  };
</PRE>

<P>According to 11.4.3 [<A href="https://wg21.link/class.mfct.non.static#2">class.mfct.non.static</A>] paragraph 2, the
transformation to class member access does not happen for
the <I>id-expression</I> <TT>a</TT>, because it is the unparenthesized
operand of <TT>&amp;</TT>:</P>

<BLOCKQUOTE>

When an <I>id-expression</I> (7.5.4 [<A href="https://wg21.link/expr.prim.id">expr.prim.id</A>]) that is
neither part of a class member access syntax
(7.6.1.5 [<A href="https://wg21.link/expr.ref">expr.ref</A>]) nor the un-parenthesized operand of the
unary &amp; operator (7.6.2.2 [<A href="https://wg21.link/expr.unary.op">expr.unary.op</A>]) is used where the
current class is X (7.5.2 [<A href="https://wg21.link/expr.prim.this">expr.prim.this</A>]), if name lookup
(6.5 [<A href="https://wg21.link/basic.lookup">basic.lookup</A>]) resolves the name in
the <I>id-expression</I> to a non-static non-type member of some class
C, and if either the <I>id-expression</I> is potentially evaluated or
C is X or a base class of X, the <I>id-expression</I> is transformed
into a class member access expression (7.6.1.5 [<A href="https://wg21.link/expr.ref">expr.ref</A>])
using (*this) as the <I>postfix-expression</I> to the left of the .
operator.  [<I>Note 1:</I> If C is not X or a base class of X, the
class member access expression is ill-formed. &#8212;<I>end
note</I>] This transformation does not apply in the template
definition context (13.8.3.2 [<A href="https://wg21.link/temp.dep.type">temp.dep.type</A>]).

</BLOCKQUOTE>

<P><B>Proposed resolution (approved by CWG 2024-03-20):</B></P>

<P>This resolution moves the transformation to
7.5.4.1 [<A href="https://wg21.link/expr.prim.id.general">expr.prim.id.general</A>], where the similar transformation for
anonymous unions is already described.</P>

<OL>

<LI>
<P>Change in 6.3 [<A href="https://wg21.link/basic.def.odr#7">basic.def.odr</A>] paragraph 7 as follows:</P>

<BLOCKQUOTE>

<TT>*this</TT> is odr-used if this appears as a potentially-evaluated
expression (including as the result of <DEL>the</DEL> <INS>any</INS>
implicit transformation <DEL>in the body of a non-static member
function</DEL> <INS>to a class member access expression</INS>
(<DEL>11.4.3 [<A href="https://wg21.link/class.mfct.non.static">class.mfct.non.static</A>]</DEL>
<INS>7.5.4.1 [<A href="https://wg21.link/expr.prim.id.general">expr.prim.id.general</A>]</INS>)).

</BLOCKQUOTE>
</LI>

<LI>
<P>Add a new paragraph before 7.5.4.1 [<A href="https://wg21.link/expr.prim.id.general#2">expr.prim.id.general</A>] paragraph 2:</P>

<BLOCKQUOTE>

<DIV class="ins">
<P>
If an <I>id-expression</I> <I>E</I> denotes a non-static non-type member of
some class <TT>C</TT> at a point where the current class
(7.5.2 [<A href="https://wg21.link/expr.prim.this">expr.prim.this</A>]) is <TT>X</TT> and
<UL class="ins">
<LI>
<I>E</I> is potentially evaluated or <TT>C</TT> is <TT>X</TT> or a
base class of <TT>X</TT>, and</LI>
<LI>
<I>E</I> is not the <I>id-expression</I> of a class member access
expression (7.6.1.5 [<A href="https://wg21.link/expr.ref">expr.ref</A>]), and</LI>
<LI>if <I>E</I> is a <I>qualified-id</I>, <I>E</I> is not the
un-parenthesized operand of the unary <TT>&amp;</TT> operator
(7.6.2.2 [<A href="https://wg21.link/expr.unary.op">expr.unary.op</A>]),</LI>
</UL>
the <I>id-expression</I> is transformed into a class member access
expression using <TT>(*this)</TT> as the object expression.
[<I>Note 1:</I> If C is not X or a base class of X, the
class member access expression is ill-formed. Also, if the <I>id-expression</I> occurs within a static or explicit object member function, the class member access is ill-formed. &#8212;<I>end
note</I>] This transformation does not apply in the template
definition context (13.8.3.2 [<A href="https://wg21.link/temp.dep.type">temp.dep.type</A>]).
</P>
</DIV>

<P>If an <I>id-expression</I> E denotes a member M of an anonymous union 
(11.5.2 [<A href="https://wg21.link/class.union.anon">class.union.anon</A>]) U:
<UL>
<LI>If U is a non-static data member, E refers to M as a member of the
lookup context of the terminal name of E (after
any <INS>implicit</INS> transformation to a class member access
expression <DEL>(11.4.3 [<A href="https://wg21.link/class.mfct.non.static">class.mfct.non.static</A>])</DEL>).</LI>
<LI>...</LI>
</UL>
</P>
</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 7.5.4.1 [<A href="https://wg21.link/expr.prim.id.general#3">expr.prim.id.general</A>] paragraph 3 as follows:</P>

<BLOCKQUOTE>

An <I>id-expression</I> that denotes a non-static data member or
implicit object member function of a class can only be used:

<UL>
<LI>as part of a class member access
(<DEL>7.6.1.5 [<A href="https://wg21.link/expr.ref">expr.ref</A>]</DEL><INS>after any implicit
transformation (see above)</INS>) in which the
object expression refers to the member's class <DEL>[ Footnote: This
also applies when the object expression is an
implicit <TT>(*this)</TT> (11.4.3 [<A href="https://wg21.link/class.mfct.non.static">class.mfct.non.static</A>]).]</DEL> or a
class derived from that class, or</LI>
<LI>...</LI>
</UL>

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 7.5.4.2 [<A href="https://wg21.link/expr.prim.id.unqual#1">expr.prim.id.unqual</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

... [ Note: ... <DEL>Within the definition of a non-static member
function, an identifier that names a non-static member is transformed
to a class member access expression
(11.4.3 [<A href="https://wg21.link/class.mfct.non.static">class.mfct.non.static</A>]).</DEL> &#8212;<I>end note</I>]

</BLOCKQUOTE>
</LI>

<LI>
<P>Remove 11.4.3 [<A href="https://wg21.link/class.mfct.non.static#2">class.mfct.non.static</A>] paragraph 2, including the example:</P>

<BLOCKQUOTE>

<DEL>When an <I>id-expression</I> (7.5.4 [<A href="https://wg21.link/expr.prim.id">expr.prim.id</A>]) that is
neither part of a class member access syntax
(7.6.1.5 [<A href="https://wg21.link/expr.ref">expr.ref</A>]) nor the un-parenthesized operand of the
unary &amp; operator (7.6.2.2 [<A href="https://wg21.link/expr.unary.op">expr.unary.op</A>]) is used where the
current class is X (7.5.2 [<A href="https://wg21.link/expr.prim.this">expr.prim.this</A>]), if name lookup
(6.5 [<A href="https://wg21.link/basic.lookup">basic.lookup</A>]) resolves the name in
the <I>id-expression</I> to a non-static non-type member of some class
C, and if either the <I>id-expression</I> is potentially evaluated or
C is X or a base class of X, the <I>id-expression</I> is transformed
into a class member access expression (7.6.1.5 [<A href="https://wg21.link/expr.ref">expr.ref</A>])
using (*this) as the <I>postfix-expression</I> to the left of the .
operator.  [<I>Note 1:</I> If C is not X or a base class of X, the
class member access expression is ill-formed. &#8212;<I>end
note</I>] This transformation does not apply in the template
definition context (13.8.3.2 [<A href="https://wg21.link/temp.dep.type">temp.dep.type</A>]). [ Example: ... ]</DEL>

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 13.8.3.2 [<A href="https://wg21.link/temp.dep.type#6">temp.dep.type</A>] paragraph 6 as follows:</P>

<BLOCKQUOTE>
[ Example: ...
<PRE>
  template int C&lt;B&gt;::g();    //<SPAN CLASS="cmnt"> OK, transformation to class member access syntax</SPAN>
                             //<SPAN CLASS="cmnt"> does not occur in the template definition context; see <DEL>11.4.3 [<A href="https://wg21.link/class.mfct.non.static">class.mfct.non.static</A>]</DEL> <INS>7.5.4.1 [<A href="https://wg21.link/expr.prim.id.general">expr.prim.id.general</A>]</INS></SPAN>
</PRE>
-- end example ]
</BLOCKQUOTE>

</LI>
</OL>

<BR><BR><HR>
<A NAME="2775"></A><H4>2775.
  
Unclear argument type for copy of exception object
</H4>
<B>Section: </B>14.2&#160; [<A href="https://wg21.link/except.throw">except.throw</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Jiang An
 &#160;&#160;&#160;

 <B>Date: </B>2023-05-31


<P>Subclause 14.2 [<A href="https://wg21.link/except.throw#5">except.throw</A>] paragraph 5 specifies:</P>

<BLOCKQUOTE>

When the thrown object is a class object, the constructor selected for
the copy-initialization as well as the constructor selected for a
copy-initialization considering the thrown object as an lvalue shall
be non-deleted and accessible, even if the copy/move operation is
elided (11.9.6 [<A href="https://wg21.link/class.copy.elision">class.copy.elision</A>]). The destructor is potentially
invoked (11.4.7 [<A href="https://wg21.link/class.dtor">class.dtor</A>]).

</BLOCKQUOTE>

<P>This provision is for capturing a copy constructor for
implementations not using reference-counted
<TT>std::exception_ptr</TT>s, but that ought to be described
separately from the "thrown object", which can be interpreted as the
operand of the <I>throw-expression</I>.</P>

<P><B>Proposed resolution (approved by CWG 2023-09-15) [SUPERSEDED]:</B></P>

<P>Change in 14.2 [<A href="https://wg21.link/except.throw#5">except.throw</A>] paragraph 5 as follows:</P>

<BLOCKQUOTE>

<DEL>When the thrown object is a class object, the constructor selected for
the copy-initialization as well as the constructor selected for a
copy-initialization considering the thrown object as an lvalue shall
be non-deleted and accessible, even if the copy/move operation is
elided (11.9.6 [<A href="https://wg21.link/class.copy.elision">class.copy.elision</A>]).</DEL>

<INS>Let <TT>T</TT> denote the type of the exception
object. Copy-initialization of an object of type <TT>T</TT> from an
lvalue of type <TT>const T</TT> in a context unrelated to any class
shall be well-formed.  If <TT>T</TT> is a class type,</INS>
<DEL>The</DEL> <INS>the</INS> destructor <INS>of <TT>T</TT></INS> is
potentially invoked (11.4.7 [<A href="https://wg21.link/class.dtor">class.dtor</A>]).

</BLOCKQUOTE>

<P><B>CWG 2023-11-09</B></P>

<P>The drafting should also consider odr-use of the constructor
potentially invoked for the copy-initialization.</P>

<P><B>Proposed resolution (approved by CWG 2023-11-10) [SUPERSEDED]:</B></P>

<OL>
<LI>
<P>Change in 6.3 [<A href="https://wg21.link/basic.def.odr#9">basic.def.odr</A>] paragraph 9 as follows:</P>

<BLOCKQUOTE>

An assignment operator function in a class is odr-used by an
implicitly-defined copy assignment or move assignment function for
another class as specified in 11.4.6 [<A href="https://wg21.link/class.copy.assign">class.copy.assign</A>]. A
constructor for a class is odr-used as specified in
9.4 [<A href="https://wg21.link/dcl.init">dcl.init</A>] <INS>and when selected for the potential
copy-initialization as specified in 14.2 [<A href="https://wg21.link/except.throw">except.throw</A>]</INS>. A
destructor for a class is odr-used if it is potentially invoked
(11.4.7 [<A href="https://wg21.link/class.dtor">class.dtor</A>]).

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 14.2 [<A href="https://wg21.link/except.throw#5">except.throw</A>] paragraph 5 as follows:</P>

<BLOCKQUOTE>

<DEL>When the thrown object is a class object, the constructor selected for
the copy-initialization as well as the constructor selected for a
copy-initialization considering the thrown object as an lvalue shall
be non-deleted and accessible, even if the copy/move operation is
elided (11.9.6 [<A href="https://wg21.link/class.copy.elision">class.copy.elision</A>]).</DEL>

<INS>Let <TT>T</TT> denote the type of the exception
object. Copy-initialization of an object of type <TT>T</TT> from an
lvalue of type <TT>const T</TT> in a context unrelated to <TT>T</TT>
shall be well-formed.  If <TT>T</TT> is a class type,</INS>
<DEL>The</DEL> <INS>the</INS> destructor <INS>of <TT>T</TT></INS> is
potentially invoked (11.4.7 [<A href="https://wg21.link/class.dtor">class.dtor</A>]).

</BLOCKQUOTE>
</LI>
</OL>

<P><B>Proposed resolution (approved by CWG 2024-03-20):</B></P>

<OL>
<LI>
<P>Change in 14.2 [<A href="https://wg21.link/except.throw#5">except.throw</A>] paragraph 5 as follows:</P>

<BLOCKQUOTE>

<DEL>When the thrown object is a class object, the constructor selected for
the copy-initialization as well as the constructor selected for a
copy-initialization considering the thrown object as an lvalue shall
be non-deleted and accessible, even if the copy/move operation is
elided (11.9.6 [<A href="https://wg21.link/class.copy.elision">class.copy.elision</A>]).</DEL>

<INS>Let <TT>T</TT> denote the type of the exception
object. Copy-initialization of an object of type <TT>T</TT> from an
lvalue of type <TT>const T</TT> in a context unrelated to <TT>T</TT>
shall be well-formed.  If <TT>T</TT> is a class type, the selected
constructor is odr-used (6.3 [<A href="https://wg21.link/basic.def.odr">basic.def.odr</A>]) and</INS>
<DEL>The</DEL> <INS>the</INS> destructor <INS>of <TT>T</TT></INS> is
potentially invoked (11.4.7 [<A href="https://wg21.link/class.dtor">class.dtor</A>]).

</BLOCKQUOTE>
</LI>
</OL>

<BR><BR><HR>
<A NAME="2777"></A><H4>2777.
  
Type of <I>id-expression</I> denoting a template parameter object
</H4>
<B>Section: </B>13.2&#160; [<A href="https://wg21.link/temp.param">temp.param</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Jim X
 &#160;&#160;&#160;

 <B>Date: </B>2023-07-26


<P>The type of a template parameter object is specified to
be <TT>const T</TT> in 13.2 [<A href="https://wg21.link/temp.param#8">temp.param</A>] paragraph 8:</P>

<BLOCKQUOTE>

An <I>id-expression</I> naming a non-type <I>template-parameter</I> of
class type T denotes a static storage duration object of
type <TT>const T</TT>, known as a template parameter object, whose
value is that of the corresponding template argument after it has been
converted to the type of the <I>template-parameter</I>.  ...

</BLOCKQUOTE>

<P>However, it is unclear what the type of an <I>id-expression</I> is
that refers to such an object.  There is implementation divergence in
the treatment of the following example:</P>

<PRE>
  struct A {};

  template&lt;auto a, auto x&gt;  // <SPAN CLASS="cmnt">also consider</SPAN> A a <SPAN CLASS="cmnt">and</SPAN> const auto x
  int f() {
    decltype(a) b;          // <SPAN CLASS="cmnt">also consider</SPAN> decltype((a))
    A&amp; rb = b;
    decltype(x) y;
    int&amp; ry = y;
  }

  int x = f&lt;A{}, 42&gt;();
</PRE>

<P>Note that non-type template parameters are handled specially for <TT>decltype</TT>, as specified in 9.2.9.6 [<A href="https://wg21.link/dcl.type.decltype#1">dcl.type.decltype</A>] paragraph 1:</P>

<BLOCKQUOTE>

For an expression E, the type denoted by <TT>decltype(E)</TT> is defined as
follows:

<UL>
<LI>...</LI>
<LI>
otherwise, if E is an unparenthesized <I>id-expression</I> naming a
non-type <I>template-parameter</I> (13.2 [<A href="https://wg21.link/temp.param">temp.param</A>]),
decltype(E) is the type of the <I>template-parameter</I> after
performing any necessary type deduction (9.2.9.7 [<A href="https://wg21.link/dcl.spec.auto">dcl.spec.auto</A>],
9.2.9.8 [<A href="https://wg21.link/dcl.type.class.deduct">dcl.type.class.deduct</A>]);
</LI>
<LI>...</LI>
</UL>

</BLOCKQUOTE>

<P><B>Proposed resolution (approved by CWG 2024-03-01):</B></P>

<P>Change in 7.5.4.2 [<A href="https://wg21.link/expr.prim.id.unqual#3">expr.prim.id.unqual</A>] paragraph 3 as follows:</P>

<BLOCKQUOTE>

... <DEL>[<I>Note 4:</I></DEL> If the entity is a template
parameter object for a template parameter
of type <TT>T</TT> (13.2 [<A href="https://wg21.link/temp.param">temp.param</A>]), the
type of the expression is <TT>const T</TT>. <DEL>&#8212;<I>end
note</I>]</DEL>
<INS>In all other cases, the type of the expression is the type of the
entity.</INS>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2803"></A><H4>2803.
  
Overload resolution for reference binding of similar types
</H4>
<B>Section: </B>12.2.4.2.5&#160; [<A href="https://wg21.link/over.ics.ref">over.ics.ref</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Brian Bi
 &#160;&#160;&#160;

 <B>Date: </B>2023-06-14




<P>Consider:</P>

<PRE>
  int foo(int*&amp; r);       //<SPAN CLASS="cmnt"> #1</SPAN>
  int foo(const int* const&amp; r); //<SPAN CLASS="cmnt"> #2</SPAN>

  int *p;
  int x = foo(p);
</PRE>

<P>Both #1 and #2 perform direct reference binding; no qualification
conversions are involved.  Despite the lack of a rule, implementations
prefer #1 over #2.</P>

<P><B>Proposed resolution (approved by CWG 2023-11-10):</B></P>

<OL>
<LI>
<P>Change in 12.2.4.2.5 [<A href="https://wg21.link/over.ics.ref#1">over.ics.ref</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

When a parameter of <DEL>reference</DEL> type <INS>"reference
to <I>cv</I> <TT>T</TT>"</INS> binds directly
(9.4.4 [<A href="https://wg21.link/dcl.init.ref">dcl.init.ref</A>]) to an argument expression<DEL>, the
implicit conversion sequence is the identity conversion,
unless</DEL><INS>:</INS>

<UL>
<LI>
<INS>If</INS> the argument
expression has a type that is a derived class of the parameter type,
<DEL>in which case</DEL> the implicit conversion sequence is a derived-to-base
conversion (12.2.4.2 [<A href="https://wg21.link/over.best.ics">over.best.ics</A>]).</LI>
<LI class="ins">
Otherwise, if <TT>T</TT> is a function type, or if the type of the
argument is possibly cv-qualified <TT>T</TT>, or if <TT>T</TT> is an
array type of unknown bound with element type <TT>U</TT> and the
argument has an array type of known bound whose element type is
possibly cv-qualified <TT>U</TT>, the implicit conversion sequence is
the identity conversion.  [ <I>Note</I>: When T is a function type,
the type of the argument may differ only by the presence
of <TT>noexcept</TT>. -- end note]
</LI>
<LI class="ins">
Otherwise, the implicit conversion sequence is a qualification
conversion.
</LI>
</UL>

<P> [<I>Example 1:</I> ... &#8212;<I>end example</I>]</P>

If the parameter binds directly to the result of applying a conversion
function to the argument expression, the implicit conversion sequence
is a user-defined conversion sequence
(12.2.4.2.3 [<A href="https://wg21.link/over.ics.user">over.ics.user</A>]) whose second standard conversion
sequence is <DEL>either an identity conversion or, if the conversion
function returns an entity of a type that is a derived class of the
parameter type, a derived-to-base conversion</DEL> <INS>determined by
the above rules</INS>.

</BLOCKQUOTE>

</LI>

<LI>
<P>Change in 12.2.4.3 [<A href="https://wg21.link/over.ics.rank#3.2.5">over.ics.rank</A>] bullet 3.2.5 as follows:</P>

<BLOCKQUOTE>

<UL>
<LI>
S1 and S2 differ only in their qualification conversion
(7.3.6 [<A href="https://wg21.link/conv.qual">conv.qual</A>]) and yield similar types T1 and T2,
respectively <INS>(where a standard conversion sequence that is a
reference binding is considered to yield the cv-unqualified referenced
type)</INS>, where T1 <DEL>can be converted to T2 by a qualification
conversion</DEL> <INS>and T2 are not the same type, and <TT>const
T2</TT> is reference-compatible with <TT>T1</TT>
(9.4.4 [<A href="https://wg21.link/dcl.init.ref">dcl.init.ref</A>])</INS>.  [<I>Example 5:</I>
<PRE>
  int f(const volatile int *);
  int f(const int *);
  int i;
  int j = f(&amp;i);  //<SPAN CLASS="cmnt"> calls </SPAN>f(const int*)
<INS>  int g(const int*);
  int g(const volatile int* const&amp;);
  int* p;
  int k = g(p);          //<SPAN CLASS="cmnt"> calls </SPAN>g(const int*)</INS>
</PRE>
  -- end example]
  or, if not that,
</LI>
</UL>
</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 12.2.4.3 [<A href="https://wg21.link/over.ics.rank#3.2.6">over.ics.rank</A>] bullet 3.2.6 as follows:</P>

<BLOCKQUOTE>

<UL>
<LI>
S1 and S2 <DEL>include reference bindings</DEL> <INS>bind "reference
to <TT>T1</TT>" and "reference to <TT>T2</TT>", respectively</INS>
(9.4.4 [<A href="https://wg21.link/dcl.init.ref">dcl.init.ref</A>]), <DEL>and the types to which the
references refer are the same type except for top-level cv-qualifiers,
and the type to which the reference initialized by S2 refers is more
cv-qualified than the type to which the reference initialized by S1
refers</DEL> <INS>where <TT>T1</TT> and <TT>T2</TT> are not the same
type, and <TT>T2</TT> is reference-compatible with <TT>T1</TT></INS>.
[<I>Example 6:</I> ...

<PRE class="ins">
   int h1(int (&amp;)[]);
   int h1(int (&amp;)[1]);
   int h2(void (&amp;)());
   int h2(void (&amp;)() noexcept);
   void g2() {
     int a[1];
     h1(a);            //<SPAN CLASS="cmnt"> calls </SPAN>h1(int (&amp;)[1])
     extern void f2() noexcept;
     h2(f2);            //<SPAN CLASS="cmnt"> calls </SPAN>h2(void (&amp;)() noexcept)
   }
</PRE>
-- end example ]
</LI>
</UL>

</BLOCKQUOTE>

</LI>
</OL>

<BR><BR><HR>
<A NAME="2809"></A><H4>2809.
  
An implicit definition does not redeclare a function
</H4>
<B>Section: </B>9.5.2&#160; [<A href="https://wg21.link/dcl.fct.def.default">dcl.fct.def.default</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Brian Bi
 &#160;&#160;&#160;

 <B>Date: </B>2023-09-27


<P>Subclause 9.5.2 [<A href="https://wg21.link/dcl.fct.def.default#5">dcl.fct.def.default</A>] paragraph 5 specifies:</P>

<BLOCKQUOTE>

... A user-provided explicitly-defaulted function (i.e., explicitly
defaulted after its first declaration) is implicitly defined at the
point where it is explicitly defaulted; if such a function is
implicitly defined as deleted, the program is ill-formed. A
non-user-provided defaulted function (i.e., implicitly declared or
explicitly defaulted in the class) that is not defined as deleted is
implicitly defined when it is odr-used (6.3 [<A href="https://wg21.link/basic.def.odr">basic.def.odr</A>]) or
needed for constant evaluation (7.7 [<A href="https://wg21.link/expr.const">expr.const</A>]).

</BLOCKQUOTE>

<P>In the first case, there is a second point of declaration for the
function, wherever the user wrote the definition.  In contrast, there
is no redeclaration for the second case, where the function is not
user-provided.  A note would clarify.</P>

<P><B>Proposed resolution (approved by CWG 2024-03-20):</B></P>

<P>Insert a paragraph break before the quoted section and change in
9.5.2 [<A href="https://wg21.link/dcl.fct.def.default#5">dcl.fct.def.default</A>] paragraph 5 as follows:</P>

<BLOCKQUOTE>

... A function is <I>user-provided</I> if it is user-declared and not
explicitly defaulted or deleted on its first declaration.
A user-provided explicitly-defaulted function (i.e., explicitly
defaulted after its first declaration) is implicitly defined at the
point where it is explicitly defaulted; if such a function is
implicitly defined as deleted, the program is ill-formed.

<INS>[<I>Note 1:</I> Declaring a function as defaulted after its first
declaration can provide efficient execution and concise definition
while enabling a stable binary interface to an evolving code
base. &#8212;<I>end note</I>]</INS>

A non-user-provided defaulted function (i.e., implicitly declared or
explicitly defaulted in the class) that is not defined as deleted is
implicitly defined when it is odr-used (6.3 [<A href="https://wg21.link/basic.def.odr">basic.def.odr</A>]) or
needed for constant evaluation (7.7 [<A href="https://wg21.link/expr.const">expr.const</A>]).

<DEL>[<I>Note 1:</I> Declaring a function as defaulted after its first
declaration can provide efficient execution and concise definition
while enabling a stable binary interface to an evolving code
base. &#8212;<I>end note</I>]</DEL>

<INS>[ Note: The implicit definition of a non-user-provided defaulted
function does not bind any names.  -- end note ]</INS>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2810"></A><H4>2810.
  
Requiring the absence of diagnostics for templates
</H4>
<B>Section: </B>13.8.1&#160; [<A href="https://wg21.link/temp.res.general">temp.res.general</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Andrey Erokhin
 &#160;&#160;&#160;

 <B>Date: </B>2022-01-23




<P>Subclause 13.8.1 [<A href="https://wg21.link/temp.res.general#6">temp.res.general</A>] paragraph 6 specifies:</P>

<BLOCKQUOTE>

The program is ill-formed, no diagnostic required, if: ...  Otherwise,
no diagnostic shall be issued for a template for which a valid
specialization can be generated.

</BLOCKQUOTE>

<P>The "Otherwise..." part is misleading; it could be interpreted to
mean that warnings must be suppressed in templates.</P>

<P><B>Proposed resolution (approved by CWG 2023-12-01):</B></P>

<P>Change in 13.8.1 [<A href="https://wg21.link/temp.res.general#6">temp.res.general</A>] paragraph 6 as follows:</P>

<BLOCKQUOTE>

<DEL>Otherwise, no diagnostic shall be issued for a template for which a
valid specialization can be generated.</DEL>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2811"></A><H4>2811.
  
Clarify "use" of main
</H4>
<B>Section: </B>6.9.3.1&#160; [<A href="https://wg21.link/basic.start.main">basic.start.main</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Jan Schultke
 &#160;&#160;&#160;

 <B>Date: </B>2023-10-12


<P>Subclause 6.9.3.1 [<A href="https://wg21.link/basic.start.main#3">basic.start.main</A>] paragraph 3 specifies:</P>

<BLOCKQUOTE>

The function main shall not be used within a program. ...

</BLOCKQUOTE>

<P>It is unclear what "use" means. N3214 excluded this appearance from
the clarifications of "use" that were turned into "odr-use".  For
example, it is unclear whether <TT>decltype(main)</TT> is allowed or
not.</P>

<P><B>CWG 2023-12-01</B></P>

<P>CWG favored to ban any mention of <TT>main</TT>.</P>

<P><B>Proposed resolution (approved by CWG 2023-12-15):</B></P>

<P>Change in 6.9.3.1 [<A href="https://wg21.link/basic.start.main#3">basic.start.main</A>] paragraph 3 as follows:</P>

<BLOCKQUOTE>

The function <TT>main</TT> shall not be <DEL>used within a
program</DEL> <INS>named by an expression</INS>. ...

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2813"></A><H4>2813.
  
Class member access with prvalues
</H4>
<B>Section: </B>7.6.1.5&#160; [<A href="https://wg21.link/expr.ref">expr.ref</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Barry Revzin
 &#160;&#160;&#160;

 <B>Date: </B>2023-08-28


<P>Subclause 7.6.1.5 [<A href="https://wg21.link/expr.ref#2">expr.ref</A>] paragraph 2 specifies:</P>

<BLOCKQUOTE>

For the first option (dot) the first expression shall be a glvalue. ...

</BLOCKQUOTE>

<P>This provision forces a temporary materialization conversion
(i.e. a copy) per 7.2.1 [<A href="https://wg21.link/basic.lval#7">basic.lval</A>] paragraph 7:</P>

<BLOCKQUOTE>

Whenever a prvalue appears as an operand of an operator that expects a
glvalue for that operand, the temporary materialization conversion
(7.3.5 [<A href="https://wg21.link/conv.rval">conv.rval</A>]) is applied to convert the expression to
an xvalue.

</BLOCKQUOTE>

<P>However, this is limiting in the case that an explicit object
member function with a by-value object parameter is invoked for a
non-copyable class object, for example:</P>

<PRE>
  struct X {
    X() = default;

    X(const X&amp;) = delete;
    X&amp; operator=(const X&amp;) = delete;

    void f(this X self) { }
  };

  void f() {
    X{}.f();   // OK?
  }
</PRE>

<P>The example ought to be well-formed.</P>

<P><B>Proposed resolution (reviewed by CWG 2024-02-16) [SUPERSEDED]:</B></P>

<OL>
<LI>
<P>Change in 6.7.7 [<A href="https://wg21.link/class.temporary#2">class.temporary</A>] paragraph 2 as follows:</P>

<BLOCKQUOTE>

... [<I>Note 3:</I> Temporary objects are materialized:
<UL>
<LI>when binding a reference to a prvalue (9.4.4 [<A href="https://wg21.link/dcl.init.ref">dcl.init.ref</A>],
7.6.1.4 [<A href="https://wg21.link/expr.type.conv">expr.type.conv</A>], 7.6.1.7 [<A href="https://wg21.link/expr.dynamic.cast">expr.dynamic.cast</A>],
7.6.1.9 [<A href="https://wg21.link/expr.static.cast">expr.static.cast</A>], 7.6.1.11 [<A href="https://wg21.link/expr.const.cast">expr.const.cast</A>],
7.6.3 [<A href="https://wg21.link/expr.cast">expr.cast</A>]),</LI>
<LI>when performing <INS>certain</INS>
member <DEL>access</DEL> <INS>accesses</INS> on a class prvalue
(7.6.1.5 [<A href="https://wg21.link/expr.ref">expr.ref</A>], 7.6.4 [<A href="https://wg21.link/expr.mptr.oper">expr.mptr.oper</A>]),</LI>
<LI class="ins">when invoking an implicit object member function on a
class prvalue (7.6.1.3 [<A href="https://wg21.link/expr.call">expr.call</A>]),</LI>
<LI>...</LI>
</UL>
&#8212;<I>end note</I>]

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 7.6.1.3 [<A href="https://wg21.link/expr.call#6">expr.call</A>] paragraph 6 as follows:</P>

<BLOCKQUOTE>

When a function is called, each parameter
(9.3.4.6 [<A href="https://wg21.link/dcl.fct">dcl.fct</A>]) is initialized
(9.4 [<A href="https://wg21.link/dcl.init">dcl.init</A>], 11.4.5.3 [<A href="https://wg21.link/class.copy.ctor">class.copy.ctor</A>]) with its
corresponding argument.  If the function is an explicit object member
function and there is an implied object argument
(12.2.2.2.2 [<A href="https://wg21.link/over.call.func">over.call.func</A>]), the list of provided arguments is
preceded by the implied object argument for the purposes of this
correspondence.  If there is no corresponding argument, the default
argument for the parameter is used.  [<I>Example 1:</I>
<PRE>
template&lt;typename ...T&gt; int f(int n = 0, T ...t);
int x = f&lt;int&gt;(); // error: no argument for second function parameter
</PRE>
&#8212;<I>end example</I>]
<INS>If the function is a static member function invoked using class
member access syntax, the object expression is a discarded-value
expression (7.2.3 [<A href="https://wg21.link/expr.context">expr.context</A>]).</INS> If the function is an
implicit object member function, <INS>the object expression of the
class member access shall be a glvalue</INS> and the <TT>this</TT>
parameter of the function (7.5.2 [<A href="https://wg21.link/expr.prim.this">expr.prim.this</A>]) is initialized
with a pointer to the object of the call, converted as if by an
explicit type conversion (7.6.3 [<A href="https://wg21.link/expr.cast">expr.cast</A>]).  [<I>Note
5:</I> There is no access or ambiguity checking on this conversion;
the access checking and disambiguation are done as part of the
(possibly implicit) class member access operator. See
6.5.2 [<A href="https://wg21.link/class.member.lookup">class.member.lookup</A>], 11.8.3 [<A href="https://wg21.link/class.access.base">class.access.base</A>], and
7.6.1.5 [<A href="https://wg21.link/expr.ref">expr.ref</A>]. &#8212;<I>end note</I>] When a function
is called, the type of any parameter shall not be a class type that is
either incomplete or abstract.  [<I>Note 6:</I> This still allows a
parameter to be a pointer or reference to such a type. However, it
prevents a passed-by-value parameter to have an incomplete or abstract
class type. &#8212;<I>end note</I>] It is implementation-defined
whether ...

</BLOCKQUOTE>

</LI>

<LI>
<P>Change in 7.6.1.5 [<A href="https://wg21.link/expr.ref#2">expr.ref</A>] paragraph 2 as follows:</P>

<BLOCKQUOTE>

For the first option (dot)<INS>, if the <I>id-expression</I> is a data
member,</INS> the first expression shall be a glvalue. For the second
option (arrow)<INS>,</INS> the first expression shall be a prvalue
having pointer type. ...

</BLOCKQUOTE>
</LI>
</OL>

<P><B>CWG 2024-02-16</B></P>

<P>When a class member access refers to a static data member or a
member enumerator, the object expression should also be treated as a
discarded-value expression.</P>

<P><B>Proposed resolution (approved by CWG 2024-03-01):</B></P>

<OL>
<LI>
<P>Change in 6.7.7 [<A href="https://wg21.link/class.temporary#2">class.temporary</A>] paragraph 2 as follows:</P>

<BLOCKQUOTE>

... [<I>Note 3:</I> Temporary objects are materialized:
<UL>
<LI>when binding a reference to a prvalue (9.4.4 [<A href="https://wg21.link/dcl.init.ref">dcl.init.ref</A>],
7.6.1.4 [<A href="https://wg21.link/expr.type.conv">expr.type.conv</A>], 7.6.1.7 [<A href="https://wg21.link/expr.dynamic.cast">expr.dynamic.cast</A>],
7.6.1.9 [<A href="https://wg21.link/expr.static.cast">expr.static.cast</A>], 7.6.1.11 [<A href="https://wg21.link/expr.const.cast">expr.const.cast</A>],
7.6.3 [<A href="https://wg21.link/expr.cast">expr.cast</A>]),</LI>
<LI>when performing <INS>certain</INS>
member <DEL>access</DEL> <INS>accesses</INS> on a class prvalue
(7.6.1.5 [<A href="https://wg21.link/expr.ref">expr.ref</A>], 7.6.4 [<A href="https://wg21.link/expr.mptr.oper">expr.mptr.oper</A>]),</LI>
<LI class="ins">when invoking an implicit object member function on a
class prvalue (7.6.1.3 [<A href="https://wg21.link/expr.call">expr.call</A>]),</LI>
<LI>...</LI>
</UL>
&#8212;<I>end note</I>]

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 7.6.1.3 [<A href="https://wg21.link/expr.call#6">expr.call</A>] paragraph 6 as follows:</P>

<BLOCKQUOTE>

When a function is called, each parameter
(9.3.4.6 [<A href="https://wg21.link/dcl.fct">dcl.fct</A>]) is initialized
(9.4 [<A href="https://wg21.link/dcl.init">dcl.init</A>], 11.4.5.3 [<A href="https://wg21.link/class.copy.ctor">class.copy.ctor</A>]) with its
corresponding argument.  If the function is an explicit object member
function and there is an implied object argument
(12.2.2.2.2 [<A href="https://wg21.link/over.call.func">over.call.func</A>]), the list of provided arguments is
preceded by the implied object argument for the purposes of this
correspondence.  If there is no corresponding argument, the default
argument for the parameter is used.  [<I>Example 1:</I>
<PRE>
template&lt;typename ...T&gt; int f(int n = 0, T ...t);
int x = f&lt;int&gt;(); // error: no argument for second function parameter
</PRE>
&#8212;<I>end example</I>] If the function is an implicit object
member function, <INS>the object expression of the class member access
shall be a glvalue</INS> and the <TT>this</TT> parameter of the
function (7.5.2 [<A href="https://wg21.link/expr.prim.this">expr.prim.this</A>]) is initialized with a pointer to
the object of the call, converted as if by an explicit type conversion
(7.6.3 [<A href="https://wg21.link/expr.cast">expr.cast</A>]).  [<I>Note 5:</I> There is no access or
ambiguity checking on this conversion; the access checking and
disambiguation are done as part of the (possibly implicit) class
member access operator. See 6.5.2 [<A href="https://wg21.link/class.member.lookup">class.member.lookup</A>],
11.8.3 [<A href="https://wg21.link/class.access.base">class.access.base</A>], and
7.6.1.5 [<A href="https://wg21.link/expr.ref">expr.ref</A>]. &#8212;<I>end note</I>] When a function
is called, the type of any parameter shall not be a class type that is
either incomplete or abstract.  [<I>Note 6:</I> This still allows a
parameter to be a pointer or reference to such a type. However, it
prevents a passed-by-value parameter to have an incomplete or abstract
class type. &#8212;<I>end note</I>] It is implementation-defined
whether ...

</BLOCKQUOTE>

</LI>

<LI>
<P>Change in 7.6.1.5 [<A href="https://wg21.link/expr.ref#2">expr.ref</A>] paragraph 2 as follows:</P>

<BLOCKQUOTE>

For the first option (dot)<INS>, if the <I>id-expression</I> names a
static member or an enumerator, the first expression is a
discarded-value expression (7.2.3 [<A href="https://wg21.link/expr.context">expr.context</A>]); if
the <I>id-expression</I> names a non-static data member,</INS> the first
expression shall be a glvalue. For the second option
(arrow)<INS>,</INS> the first expression shall be a prvalue having
pointer type. ...

</BLOCKQUOTE>
</LI>
</OL>

<BR><BR><HR>
<A NAME="2820"></A><H4>2820.
  
Value-initialization and default constructors
</H4>
<B>Section: </B>9.4.1&#160; [<A href="https://wg21.link/dcl.init.general">dcl.init.general</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Shafik Yaghmour
 &#160;&#160;&#160;

 <B>Date: </B>2023-10-31




<P>Subclause 9.4.1 [<A href="https://wg21.link/dcl.init.general#9">dcl.init.general</A>] paragraph 9 specifies:</P>

<BLOCKQUOTE>

To value-initialize an object of type T means:
<UL>
<LI>if T is a (possibly
cv-qualified) class type (Clause Clause 11 [<A href="https://wg21.link/class">class</A>]), then
<UL>
<LI>
if T has either no default constructor
(11.4.5.2 [<A href="https://wg21.link/class.default.ctor">class.default.ctor</A>]) or a default constructor that is
user-provided or deleted, then the object is default-initialized;
</LI>
<LI>
otherwise, the object is zero-initialized and the semantic
constraints for default-initialization are checked, and if T has a
non-trivial default constructor, the object is default-initialized;
</LI>
</UL>
</LI>
<LI>if T is an array type, ...
</LI>
</UL>

</BLOCKQUOTE>

<P>The specification about checking the semantic constraints and
invoking only non-trivial default constructors is overly convoluted.
Omitting a call to a trivial constructor is an as-if optimization that
should not be prescribed by the standard.</P>

<P><B>Proposed resolution (approved by CWG 2024-01-19):</B></P>

<P>Change in 9.4.1 [<A href="https://wg21.link/dcl.init.general#9.1.2">dcl.init.general</A>] bullet 9.1.2 as follows:</P>

<BLOCKQUOTE>

<UL>
<LI>...</LI>
<LI>
otherwise, the object is zero-initialized and <DEL>the semantic
constraints for default-initialization are checked, and if T has a
non-trivial default constructor, the object is</DEL> <INS>then</INS>
default-initialized;
</LI>
</UL>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2822"></A><H4>2822.
  
Side-effect-free pointer zap
</H4>
<B>Section: </B>6.7.5.1&#160; [<A href="https://wg21.link/basic.stc.general">basic.stc.general</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Davis Herring
 &#160;&#160;&#160;

 <B>Date: </B>2023-11-06




<P>Subclause 6.7.5.1 [<A href="https://wg21.link/basic.stc.general#4">basic.stc.general</A>] paragraph 4 seems to suggest
that the end of duration of a region of storage causes actual
modifications to pointer objects, causing questions about data races
(in the abstract machine).</P>

<P><B>Proposed resolution (approved by CWG 2024-03-20):</B></P>

<OL>
<LI>
<P>Append to 6.7.5.1 [<A href="https://wg21.link/basic.stc.general#1">basic.stc.general</A>] paragraph 1:</P>

<BLOCKQUOTE class="ins">

[ Note: After the duration of a region of storage has ended, the use of
pointers to that region of storage is limited
(6.8.4 [<A href="https://wg21.link/basic.compound">basic.compound</A>]).  -- end note ]

</BLOCKQUOTE>
</LI>

<LI>
<P>Remove 6.7.5.1 [<A href="https://wg21.link/basic.stc.general#4">basic.stc.general</A>] paragraph 4 as follows:</P>

<BLOCKQUOTE class="del">

When the end of the duration of a region of storage is reached,
the values of all pointers representing the address of any part of
that region of storage become invalid pointer values
(6.8.4 [<A href="https://wg21.link/basic.compound">basic.compound</A>]). Indirection through an invalid pointer
value and passing an invalid pointer value to a deallocation function
have undefined behavior.  Any other use of an invalid pointer value
has implementation-defined behavior. [ Footnote: ... ]

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 6.8.4 [<A href="https://wg21.link/basic.compound#3">basic.compound</A>] paragraph 3 as follows:</P>

<BLOCKQUOTE>

[<I>Note 2:</I> A pointer past the end of an object
(7.6.6 [<A href="https://wg21.link/expr.add">expr.add</A>]) is not considered to point to an
unrelated object of the object's type, even if the unrelated object is
located at that address. <DEL>A pointer value becomes invalid when the
storage it denotes reaches the end of its storage duration; see
6.7.5 [<A href="https://wg21.link/basic.stc">basic.stc</A>].</DEL> &#8212;<I>end note</I>]

</BLOCKQUOTE>
</LI>

<LI>
<P>Insert a new paragraph after 6.8.4 [<A href="https://wg21.link/basic.compound#3">basic.compound</A>] paragraph 3:</P>

<BLOCKQUOTE class="ins">
A pointer value <I>P</I> is <I>valid in the context of</I> an
evaluation <I>E</I> if <I>P</I> is a null pointer value, or if it is a
pointer to or past the end of an object <I>O</I> and <I>E</I> happens
before the end of the duration of the region of storage
for <I>O</I>. If a pointer value <I>P</I> is used in an
evaluation <I>E</I> and <I>P</I> is not valid in the context
of <I>E</I>, then the behavior is undefined if <I>E</I> is an
indirection (7.6.2.2 [<A href="https://wg21.link/expr.unary.op">expr.unary.op</A>]) or an invocation of a
deallocation function (6.7.5.5.3 [<A href="https://wg21.link/basic.stc.dynamic.deallocation">basic.stc.dynamic.deallocation</A>]), and
implementation-defined otherwise. [ Footnote: Some implementations
might define that copying such a pointer value causes a
system-generated runtime fault. -- end footnote ]

[ Note: <I>P</I> can be valid in the context of <I>E</I> even if it
points to a type unrelated to that of <I>O</I> or if <I>O</I> is not
within its lifetime, although further restrictions apply to such
pointer values (6.7.3 [<A href="https://wg21.link/basic.life">basic.life</A>],
7.2.1 [<A href="https://wg21.link/basic.lval">basic.lval</A>], 7.6.6 [<A href="https://wg21.link/expr.add">expr.add</A>]). &#8212;<I>end
note</I>]

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 7.6.1.9 [<A href="https://wg21.link/expr.static.cast#14">expr.static.cast</A>] paragraph 14 as follows:</P>

<BLOCKQUOTE>

... If the original pointer value represents the address A of a byte
in memory and A does not satisfy the alignment requirement of T, then
the resulting pointer value <INS>(6.8.4 [<A href="https://wg21.link/basic.compound">basic.compound</A>])</INS> is
unspecified. ...

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 7.6.1.10 [<A href="https://wg21.link/expr.reinterpret.cast#5">expr.reinterpret.cast</A>] paragraph 5 as follows:</P>

<BLOCKQUOTE>

A value of integral type or enumeration type can be explicitly
converted to a pointer. A pointer converted to an integer of
sufficient size (if any such exists on the implementation) and back to
the same pointer type will have its original value
<INS>(6.8.4 [<A href="https://wg21.link/basic.compound">basic.compound</A>])</INS>; mappings between
pointers and integers are otherwise implementation-defined.

</BLOCKQUOTE>
</LI>
</OL>

<BR><BR><HR>
<A NAME="2824"></A><H4>2824.
  
Copy-initialization of arrays
</H4>
<B>Section: </B>9.4.1&#160; [<A href="https://wg21.link/dcl.init.general">dcl.init.general</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Anoop Rana
 &#160;&#160;&#160;

 <B>Date: </B>2023-11-06


<P>Consider:</P>

<PRE>
  std::string arr[] = "some string";
</PRE>

<P>Prior to the application of paper P0960R3 (Allow initializing
aggregates from a parenthesized list of values), this was ill-formed,
but now it is well-formed.  However, the specification talks about
an <I>expression-list</I> as part of the initializer, which does not
exist in this case.</P>

<P><B>Proposed resolution (approved by CWG 2023-11-07):</B></P>

<P>Change in 9.4.1 [<A href="https://wg21.link/dcl.init.general#16.5">dcl.init.general</A>] bullet 16.5 as follows:</P>

<BLOCKQUOTE>

Otherwise, if the destination type is an array, the object is
initialized as follows. <INS>The <I>initializer</I> shall be of the
form <TT>(</TT> <I>expression-list</I> <TT>)</TT>.</INS> Let x1 , . . . , xk
be the elements of the <I>expression-list</I>. If the destination type
is an array of unknown bound, it is defined as having k elements. Let
n denote the array size after this potential adjustment. If k is
greater than n, the program is ill-formed. Otherwise, ...

</BLOCKQUOTE>
<BR><BR><HR>
<A NAME="2825"></A><H4>2825.
  
Range-based for statement using a <I>braced-init-list</I>
</H4>
<B>Section: </B>8.6.5&#160; [<A href="https://wg21.link/stmt.ranged">stmt.ranged</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Arthur O'Dwyer
 &#160;&#160;&#160;

 <B>Date: </B>2023-11-08


<P>Consider:</P>

<PRE>
  for (int i : { 1, 2, 3 })  // <SPAN CLASS="cmnt">argument-dependent lookup for </SPAN>begin(std::initializer_list&lt;int&gt;)
    /* ... */;
</PRE>

<P>This is undesirable; instead, a member function <TT>begin</TT> should be preferred.</P>

<P><B>Proposed resolution (approved by CWG 2023-11-09):</B></P>

<P>Change in 8.6.5 [<A href="https://wg21.link/stmt.ranged#1.3">stmt.ranged</A>] bullet 1.3 as follows:</P>

<BLOCKQUOTE>

<I>begin-expr</I> and <I>end-expr</I> are determined as follows:

<UL>
<LI>if the <DEL><I>for-range-initializer</I> is an expression of</DEL>
<INS>type of <I>range</I> is a reference to an</INS> array type
R, <I>begin-expr</I> and <I>end-expr</I> are range and range + N,
respectively, where N is the array bound. If R is an array of unknown
bound or an array of incomplete type, the program is ill-formed;</LI>

<LI>if the <DEL><I>for-range-initializer</I> is an expression of</DEL>
<INS>type of <I>range</I> is a reference to a</INS> class type
C, and searches in the scope of C (6.5.2 [<A href="https://wg21.link/class.member.lookup">class.member.lookup</A>]) for the
names begin and end each find at least one
declaration, <I>begin-expr</I> and <I>end-expr</I> are range .begin()
and range .end(), respectively;</LI>

<LI>otherwise, <I>begin-expr</I> and <I>end-expr</I> are begin(range )
and end(range ), respectively, where begin and end undergo
argument-dependent lookup (6.5.4 [<A href="https://wg21.link/basic.lookup.argdep">basic.lookup.argdep</A>]).  [<I>Note
1:</I> Ordinary unqualified lookup (6.5.3 [<A href="https://wg21.link/basic.lookup.unqual">basic.lookup.unqual</A>]) is not
performed. &#8212;<I>end note</I>]</LI>
</UL>

</BLOCKQUOTE>

<P><B>Additional notes (November, 2023)</B></P>

<P>Forwarded to EWG via
<A HREF="https://github.com/cplusplus/papers/issues/1694">paper issue 1694</A>
for confirmation of the design direction.</P>

<P><B>EWG 2023-11-09</B></P>

<P>Approved by EWG.</P>

<BR><BR><HR>
<A NAME="2828"></A><H4>2828.
  
Ambiguous interpretation of C-style cast
</H4>
<B>Section: </B>7.6.3&#160; [<A href="https://wg21.link/expr.cast">expr.cast</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Jim X
 &#160;&#160;&#160;

 <B>Date: </B>2022-03-21


<P>(From editorial issue
<A HREF="https://github.com/cplusplus/draft/issues/5355">5355</A>.)</P>

<P>Consider:</P>

<PRE>
   int*** ptr = 0;
   auto t = (int const*const*const*)ptr;
</PRE>

<P>There is more than one way how this can be interpreted as
a <TT>static_cast</TT> followed by a <TT>const_cast</TT>, namely:</P>

<PRE>
  const_cast&lt;int const * const * const * &gt;(static_cast&lt;int * * const * &gt;(ptr));
  const_cast&lt;int const * const * const * &gt;(static_cast&lt;int * const * const * &gt;(ptr));
</PRE>

<P>Subclause 7.6.3 [<A href="https://wg21.link/expr.cast#4">expr.cast</A>] paragraph 4 makes such a program ill-formed:</P>

<BLOCKQUOTE>

... If a conversion can be interpreted in more than one way as a
<TT>static_cast</TT> followed by a <TT>const_cast</TT>, the conversion
is ill-formed.

</BLOCKQUOTE>

<P><B>Proposed resolution (approved by CWG 2024-03-20):</B></P>

<P>Change in 7.6.3 [<A href="https://wg21.link/expr.cast#4">expr.cast</A>] paragraph 4 as follows:</P>

<BLOCKQUOTE>

... If a conversion can be interpreted in more than one of the ways listed
above, the interpretation that appears first in the list is used, even
if a cast resulting from that interpretation is ill-formed. If a
<DEL>conversion can be interpreted in more than one way as
a</DEL> <TT>static_cast</TT> followed by a <TT>const_cast</TT> <INS>is
used and the conversion can be interpreted in more than one way as
such</INS>, the conversion is ill-formed.
[ Example 1 :
<PRE>
  struct A { };
  struct I1 : A { };
  struct I2 : A { };
  struct D : I1, I2 { };
  A* foo( D* p ) {
    return (A*)( p );  //<SPAN CLASS="cmnt"> ill-formed static_cast interpretation</SPAN>
  }

<INS>  int*** ptr = 0;
  auto t = (int const*const*const*)ptr;  //<SPAN CLASS="cmnt"> OK, </SPAN>const_cast<SPAN CLASS="cmnt"> interpretation</SPAN>

  struct S {
    operator const int*();
    operator volatile int*();
  };
  int *p = (int*)S();  //<SPAN CLASS="cmnt"> error: two possible interpretations using </SPAN>static_cast<SPAN CLASS="cmnt"> followed by </SPAN>const_cast</INS>
</PRE>
-- end example ]

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2830"></A><H4>2830.
  
Top-level cv-qualification should be ignored for list-initialization
</H4>
<B>Section: </B>9.4.5&#160; [<A href="https://wg21.link/dcl.init.list">dcl.init.list</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Krystian Stasiowski
 &#160;&#160;&#160;

 <B>Date: </B>2019-11-19


<P>(From editorial issue
<A HREF="https://github.com/cplusplus/draft/issues/3492">3492</A>.)</P>

<P>Subclause 9.4.5 [<A href="https://wg21.link/dcl.init.list#3">dcl.init.list</A>] paragraph 3 specifies:</P>

<BLOCKQUOTE>

List-initialization of an object or reference of type <TT>T</TT> is
defined as follows:
<UL>
<LI>...</LI>
</UL>

</BLOCKQUOTE>

<P>Top-level cv-qualifiers should be ignored when comparing <TT>T</TT>
to other types, e.g. in 9.4.5 [<A href="https://wg21.link/dcl.init.list#3.2">dcl.init.list</A>] bullet 3.2.</P>

<P><B>Proposed resolution (approved by CWG 2024-01-19):</B></P>

<P>Change in 9.4.5 [<A href="https://wg21.link/dcl.init.list#3">dcl.init.list</A>] paragraph 3 as follows:</P>

<BLOCKQUOTE>

List-initialization of an object or reference of
type <INS><I>cv</I></INS> <TT>T</TT> is defined as follows:
<UL>
<LI>...</LI>
<LI>If T is an aggregate class and the initializer list has a single
element of type <DEL><I>cv</I></DEL> <INS><I>cv1</I></INS> <TT>U</TT>,
where U is T or a class derived from T, the object is initialized from
that element (by copy-initialization for copy-list-initialization, or
by direct-initialization for direct-list-initialization).
</LI>
<LI>...</LI>
</UL>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2831"></A><H4>2831.
  
Non-templated function definitions and <I>requires-clause</I>s
</H4>
<B>Section: </B>9.3.1&#160; [<A href="https://wg21.link/dcl.decl.general">dcl.decl.general</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Krystian Stasiowski
 &#160;&#160;&#160;

 <B>Date: </B>2020-04-13


<P>(From editorial issue
<A HREF="https://github.com/cplusplus/draft/issues/3936">3936</A>.)</P>

<P>Subclause 9.3.1 [<A href="https://wg21.link/dcl.decl.general#4">dcl.decl.general</A>] paragraph 4 specifies:</P>

<BLOCKQUOTE>

The optional <I>requires-clause</I> in an <I>init-declarator</I>
or <I>member-declarator</I> shall be present only if the declarator
declares a templated function (13.1 [<A href="https://wg21.link/temp.pre">temp.pre</A>]). ...

</BLOCKQUOTE>

<P>This rule does not address function definitions, because those have
neither an <I>init-declarator</I> nor a <I>member-declarator</I>.</P>

<P><B>Proposed resolution (approved by CWG 2024-03-20):</B></P>

<P>Change in 9.5.1 [<A href="https://wg21.link/dcl.fct.def.general#1">dcl.fct.def.general</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

...  The optional <I>attribute-specifier-seq</I> in
a <I>function-definition</I> appertains to the
function.

A <DEL><I>virt-specifier-seq</I> can be
part of a <I>function-definition</I> only if it is</DEL>
<INS><I>function-definition</I> with a <I>virt-specifier-seq</I> shall be</INS>
a <I>member-declaration</I> (11.4 [<A href="https://wg21.link/class.mem">class.mem</A>]). <INS>A <I>function-definition</I> with
a <I>requires-clause</I> shall define a templated function.</INS>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2845"></A><H4>2845.
  
Make the closure type of a captureless lambda a structural type
</H4>
<B>Section: </B>7.5.5.2&#160; [<A href="https://wg21.link/expr.prim.lambda.closure">expr.prim.lambda.closure</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Barry Revzin
 &#160;&#160;&#160;

 <B>Date: </B>2023-12-29




<P>Issue 2542 (approved in June, 2023) made
all closure types not be structural types, i.e. unsuitable for use as
non-type template parameters.  This causes an inconsistency with the
treatment of the pointer-to-function conversion for closure types with
no captures:</P>

<PRE>
  template &lt;auto V&gt;
  void foo() {}

  void bar() {
    foo&lt;[i = 3] { return i; }&gt;();   //<SPAN CLASS="cmnt"> #1: error</SPAN>
    foo&lt;[]{}&gt;();                    //<SPAN CLASS="cmnt"> #2: error</SPAN>
    foo&lt;+[]{}&gt;();                   //<SPAN CLASS="cmnt"> #3: OK, a function pointer is a structural type</SPAN>
  }
</PRE>

<P><B>Proposed resolution (approved by CWG 2024-02-02):</B></P>

<OL>
<LI>
<P>Change in 7.5.5.2 [<A href="https://wg21.link/expr.prim.lambda.closure#3">expr.prim.lambda.closure</A>] paragraph 3 as follows:</P>

<BLOCKQUOTE>

The closure type is not an aggregate type (9.4.2 [<A href="https://wg21.link/dcl.init.aggr">dcl.init.aggr</A>])
<DEL>and not</DEL> <INS>; it is</INS> a structural type
(13.2 [<A href="https://wg21.link/temp.param">temp.param</A>])
<INS>if and only if the lambda has no <I>lambda-capture</I></INS>. An
implementation may define the closure type differently from ...

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 13.6 [<A href="https://wg21.link/temp.type#2">temp.type</A>] paragraph 2 as follows:</P>

<BLOCKQUOTE>

Two values are <I>template-argument-equivalent</I> if they are of the
same type and
<UL>
<LI>...</LI>
<LI class="ins">they are of a closure type
(7.5.5.2 [<A href="https://wg21.link/expr.prim.lambda.closure">expr.prim.lambda.closure</A>]), or</LI>
<LI>they are of class type and their corresponding direct subobjects
and reference members are template-argument-equivalent.</LI>
</UL>

</BLOCKQUOTE>

</LI>
</OL>
<BR><BR><HR>
<A NAME="2846"></A><H4>2846.
  
Out-of-class definitions of explicit object member functions
</H4>
<B>Section: </B>9.3.4.6&#160; [<A href="https://wg21.link/dcl.fct">dcl.fct</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Krystian Stasiowski
 &#160;&#160;&#160;

 <B>Date: </B>2024-01-28


<P>(From submission
<A HREF="https://github.com/cplusplus/CWG/issues/493">#493</A>.)</P>

<P>Consider:</P>

<PRE>
  struct A {
    void f(this A&amp;);
  };
  void A::f(this A&amp;) { }    // <SPAN CLASS="cmnt">#1</SPAN>
</PRE>

<P>This is accepted by all major implementations.  However,
9.3.4.6 [<A href="https://wg21.link/dcl.fct#6">dcl.fct</A>] paragraph 6 specifies:</P>

<BLOCKQUOTE>

An <I>explicit-object-parameter-declaration</I> is
a <I>parameter-declaration</I> with a this specifier. An
explicit-object-parameter-declaration shall appear only as the
first <I>parameter-declaration</I> of
a <I>parameter-declaration-list</I> of either:
<UL>
<LI>a <I>member-declarator</I> that declares a member function
(11.4 [<A href="https://wg21.link/class.mem">class.mem</A>]), or</LI>
<LI>a <I>lambda-declarator</I> (7.5.5 [<A href="https://wg21.link/expr.prim.lambda">expr.prim.lambda</A>]).</LI>
</UL>
A <I>member-declarator</I> with an
explicit-object-parameter-declaration shall not include
a <I>ref-qualifier</I> or a <I>cv-qualifier-seq</I> and shall not be
declared static or virtual.

</BLOCKQUOTE>

<P>The <I>function-definition</I> at #1 is neither of the two allowed
options.</P>

<P>Similar concerns arise for explicit instantiations and explicit
specializations.</P>

<P><B>Proposed resolution (approved by CWG 2024-02-16):</B></P>

<P>Change in 9.3.4.6 [<A href="https://wg21.link/dcl.fct#6">dcl.fct</A>] paragraph 6 as follows:</P>

<BLOCKQUOTE>

An <I>explicit-object-parameter-declaration</I> is
a <I>parameter-declaration</I> with a this specifier. An
explicit-object-parameter-declaration shall appear only as the
first <I>parameter-declaration</I> of a
<I>parameter-declaration-list</I> of <DEL>either</DEL> <INS>one of</INS>:
<UL>
<LI>a <DEL><I>member-declarator</I> that declares</DEL>
<INS>declaration of</INS> a member function <INS>or member function
template</INS> (11.4 [<A href="https://wg21.link/class.mem">class.mem</A>]), or</LI>
<LI class="ins">an explicit instantiation
(13.9.3 [<A href="https://wg21.link/temp.explicit">temp.explicit</A>]) or explicit specialization
(13.9.4 [<A href="https://wg21.link/temp.expl.spec">temp.expl.spec</A>]) of a templated member function, or</LI>
<LI>a <I>lambda-declarator</I> (7.5.5 [<A href="https://wg21.link/expr.prim.lambda">expr.prim.lambda</A>]).</LI>
</UL>
A <I>member-declarator</I> with an
explicit-object-parameter-declaration shall not include
a <I>ref-qualifier</I> or a <I>cv-qualifier-seq</I> and shall not be
declared static or virtual.

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2848"></A><H4>2848.
  
Omitting an empty template argument list for explicit instantiation
</H4>
<B>Section: </B>13.9.3&#160; [<A href="https://wg21.link/temp.explicit">temp.explicit</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Anoop Rana
 &#160;&#160;&#160;

 <B>Date: </B>2024-01-15


<P>(From submission
<A HREF="https://github.com/cplusplus/CWG/issues/489">#489</A>.)</P>

<P>Subclause 13.9.3 [<A href="https://wg21.link/temp.explicit#8">temp.explicit</A>] paragraph 8 specifies:</P>

<BLOCKQUOTE>

A trailing <I>template-argument</I> can be left unspecified in an
explicit instantiation of a function template specialization or of a
member function template specialization provided it can be deduced
(13.10.3.7 [<A href="https://wg21.link/temp.deduct.decl">temp.deduct.decl</A>]). If all template arguments can be
deduced, the empty template argument list &lt;&gt; may be omitted.
[<I>Example 3:</I>

<PRE>
  template&lt;class T&gt; class Array { /* ... */ };
  template&lt;class T&gt; void sort(Array&lt;T&gt;&amp; v) { /* ... */ }

  //<SPAN CLASS="cmnt"> instantiate sort(Array&lt;int&gt;&amp;) -- template-argument deduced</SPAN>
  template void sort&lt;&gt;(Array&lt;int&gt;&amp;);
</PRE>
&#8212;<I>end example</I>]

</BLOCKQUOTE>

<P>This paragraph is redundant with a more general provision on
explicitly specifying template arguments in 13.10.2 [<A href="https://wg21.link/temp.arg.explicit#4">temp.arg.explicit</A>] paragraph 4:</P>

<BLOCKQUOTE>

Trailing template arguments that can be deduced
(13.10.3 [<A href="https://wg21.link/temp.deduct">temp.deduct</A>]) or obtained from
default <I>template-argument</I>s may be omitted from the list of
explicit <I>template-argument</I>s.  [<I>Note 1:</I> A trailing
template parameter pack (13.7.4 [<A href="https://wg21.link/temp.variadic">temp.variadic</A>]) not otherwise
deduced will be deduced as an empty sequence of template
arguments. &#8212;<I>end note</I>] If all of the template arguments
can be deduced or obtained from default <I>template-argument</I>s,
they may all be omitted; in this case, the empty template argument
list &lt;&gt; itself may also be omitted. ...

</BLOCKQUOTE>

<P>A similar duplication is in 13.9.4 [<A href="https://wg21.link/temp.expl.spec#10">temp.expl.spec</A>] paragraph 10.</P>

<P><B>Proposed resolution (approved by CWG 2024-02-16):</B></P>

<OL>
<LI>
<P>Change the example in 13.9.3 [<A href="https://wg21.link/temp.explicit#4">temp.explicit</A>] paragraph 4 as follows:</P>

<PRE>
  ...
  template&lt;class T&gt; void sort(Array&lt;T&gt;&amp; v) { /* ... */ }
  template void sort(Array&lt;char&gt;&amp;);  //<SPAN CLASS="cmnt"> argument is deduced here <INS>(13.10.2 [<A href="https://wg21.link/temp.arg.explicit">temp.arg.explicit</A>])</INS></SPAN>
  ...
</PRE>
</LI>

<LI>
<P>Remove 13.9.3 [<A href="https://wg21.link/temp.explicit#8">temp.explicit</A>] paragraph 8:</P>

<BLOCKQUOTE class="del">

A trailing <I>template-argument</I> can be left unspecified in an
explicit instantiation of a function template specialization or of a
member function template specialization provided it can be deduced
(13.10.3.7 [<A href="https://wg21.link/temp.deduct.decl">temp.deduct.decl</A>]). If all template arguments can be
deduced, the empty template argument list &lt;&gt; may be omitted.
[<I>Example 3:</I>

<PRE>
  template&lt;class T&gt; class Array { /* ... */ };
  template&lt;class T&gt; void sort(Array&lt;T&gt;&amp; v) { /* ... */ }

  //<SPAN CLASS="cmnt"> instantiate sort(Array&lt;int&gt;&amp;) -- template-argument deduced</SPAN>
  template void sort&lt;&gt;(Array&lt;int&gt;&amp;);
</PRE>
&#8212;<I>end example</I>]

</BLOCKQUOTE>

</LI>

<LI>
<P>Change the example in 13.9.4 [<A href="https://wg21.link/temp.expl.spec#1">temp.expl.spec</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>
... [ Example:
<PRE>
  template&lt;class T&gt; class stream;
  template&lt;&gt; class stream&lt;char&gt; { /* ... */ };<INS> // <SPAN CLASS="cmnt">#1</SPAN></INS>

  template&lt;class T&gt; class Array { /* ... */ };
  template&lt;class T&gt; void sort(Array&lt;T&gt;&amp; v) { /* ... */ }

  <INS>template&lt;&gt; void sort&lt;int&gt;(Array&lt;int&gt;&amp;);   // <SPAN CLASS="cmnt">#2</SPAN></INS>
  template&lt;&gt; void sort<DEL>&lt;char*&gt;</DEL>(Array&lt;char*&gt;&amp;);   <INS>// <SPAN CLASS="cmnt">#3 template argument is deduced (13.10.2 [<A href="https://wg21.link/temp.arg.explicit">temp.arg.explicit</A>])</SPAN></INS>
  ...
</PRE>

Given these declarations, <DEL>stream&lt;char&gt;</DEL> <INS>#1</INS>
will be used as the definition of streams of chars; other streams will
be handled by class template specializations instantiated from the
class template. Similarly, <INS>#2 will be used as the sort function
for arguments of type <TT>Array&lt;int&gt;</TT> and
#3</INS> <DEL>sort&lt;char*&gt;</DEL> will be used <DEL>as the sort
function</DEL> for arguments of type <TT>Array&lt;char*&gt;</TT>; other Array
types will be sorted by functions generated from
the <INS>function</INS> template. &#8212;<I>end example</I>]

</BLOCKQUOTE>
</LI>

<LI>
<P>Remove 13.9.4 [<A href="https://wg21.link/temp.expl.spec#10">temp.expl.spec</A>] paragraph 10:</P>

<BLOCKQUOTE class="del">

A trailing <I>template-argument</I> can be left unspecified in
the <I>template-id</I> naming an explicit function template
specialization provided it can be deduced
(13.10.3.7 [<A href="https://wg21.link/temp.deduct.decl">temp.deduct.decl</A>]).  [<I>Example 6:</I>
<PRE>
  template&lt;class T&gt; class Array { /* ... */ };
  template&lt;class T&gt; void sort(Array&lt;T&gt;&amp; v);

  //<SPAN CLASS="cmnt"> explicit specialization for sort(Array&lt;int&gt;&amp;)</SPAN>
  //<SPAN CLASS="cmnt"> with deduced template-argument of type int</SPAN>
  template&lt;&gt; void sort(Array&lt;int&gt;&amp;);
</PRE>
&#8212;<I>end example</I>]

</BLOCKQUOTE>
</LI>
</OL>

<BR><BR><HR>
<A NAME="2849"></A><H4>2849.
  
Parameter objects are not temporary objects
</H4>
<B>Section: </B>6.7.7&#160; [<A href="https://wg21.link/class.temporary">class.temporary</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Brian Bi
 &#160;&#160;&#160;

 <B>Date: </B>2024-01-20


<P>(From submission
<A HREF="https://github.com/cplusplus/CWG/issues/490">#490</A>.)</P>

<P>Parameter objects are not temporary objects, according to
6.7.7 [<A href="https://wg21.link/class.temporary#1">class.temporary</A>] paragraph 1.  An exception hinting at this in
6.7.7 [<A href="https://wg21.link/class.temporary#7">class.temporary</A>] paragraph 7 should be removed.</P>

<P><B>Proposed resolution (approved by CWG 2024-02-02):</B></P>

<P>Change in 6.7.7 [<A href="https://wg21.link/class.temporary#7">class.temporary</A>] paragraph 7 as follows:</P>

<BLOCKQUOTE>

The fourth context is when a temporary object <DEL>other than a
function parameter object</DEL> is created in
the <I>for-range-initializer</I> of a range-based for statement. If
such a temporary object would otherwise be destroyed at the end of
the <I>for-range-initializer</I> full-expression, the object persists
for the lifetime of the reference initialized by
the <I>for-range-initializer</I>.

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2850"></A><H4>2850.
  
Unclear storage duration for function parameter objects
</H4>
<B>Section: </B>6.7.5&#160; [<A href="https://wg21.link/basic.stc">basic.stc</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Brian Bi
 &#160;&#160;&#160;

 <B>Date: </B>2024-02-03


<P>(From submission
<A HREF="https://github.com/cplusplus/CWG/issues/490">#490</A>.)</P>

<P>Function parameter objects have automatic storage duration and are
not temporary objects (see also issue 2849).  However, it is unclear how long the storage for
function parameter objects lasts.</P>

<P>Furthermore, for temporary objects that are destroyed at the end of
the full-expression, it is unclear how the destruction is ordered with
respect to temporary objects destroyed at the end of the
full-expression.</P>

<P><B>Proposed resolution (approved by CWG 2024-03-20):</B></P>

<OL>
<LI>
<P>Change in and combine 6.7.5.4 [<A href="https://wg21.link/basic.stc.auto#1">basic.stc.auto</A>] paragraph 1 and 2
as follows:</P>

<BLOCKQUOTE>

<P>
Variables that belong to a block <DEL>or parameter</DEL> scope and are
not explicitly declared static, thread_local, or extern have automatic
storage duration. The storage for <DEL>these entities</DEL><INS>such
variables</INS> lasts until the block in which they are created
exits. [Note 1: These variables are initialized and destroyed as
described in 8.8 [stmt.dcl]. -- end note]
</P>

<P class="ins">Variables that belong to a parameter scope also have automatic
storage duration.  The storage for a function parameter lasts until
immediately after its destruction (7.6.1.3 [expr.call]).
</P>

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 6.7.7 [<A href="https://wg21.link/class.temporary#8">class.temporary</A>] paragraph 8 as follows:</P>

<BLOCKQUOTE>

<DEL>The destruction of a temporary whose lifetime is not extended beyond
the full-expression in which it was created is sequenced before the
destruction of every temporary which is constructed earlier in the
same full-expression.</DEL>
<INS>Let <TT>x</TT> and <TT>y</TT> each be either a temporary object
whose lifetime is not extended, or a function parameter. If the
lifetimes of <TT>x</TT> and <TT>y</TT> end at the end of the same
full-expression, and <TT>x</TT> is initialized
before <TT>y</TT>, then the destruction of <TT>y</TT> is
sequenced before that of <TT>x</TT>.</INS>
If the lifetime of two or more temporaries with
lifetimes extending beyond the full-expressions in which they were
created ends at the same point, these temporaries are destroyed at
that point in the reverse order of the completion of their
construction. In addition, the destruction of such temporaries shall
take into account the ordering of destruction of objects with static,
thread, or automatic storage duration (6.7.5.2 [<A href="https://wg21.link/basic.stc.static">basic.stc.static</A>],
6.7.5.3 [<A href="https://wg21.link/basic.stc.thread">basic.stc.thread</A>], 6.7.5.4 [<A href="https://wg21.link/basic.stc.auto">basic.stc.auto</A>]); that is,
if obj1 is an object with the same storage duration as the temporary
and created before the temporary is created the temporary shall be
destroyed before obj1 is destroyed; if obj2 is an object with the same
storage duration as the temporary and created after the temporary is
created the temporary shall be destroyed after obj2 is destroyed.

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 7.6.1.3 [<A href="https://wg21.link/expr.call#6">expr.call</A>] paragraph 6 as follows:</P>

<BLOCKQUOTE>

... It is implementation-defined whether <DEL>the lifetime of</DEL> a parameter
<DEL>ends</DEL> <INS>is destroyed</INS> when the function in which it
is defined <DEL>returns</DEL> <INS>exits (8.7.4 [<A href="https://wg21.link/stmt.return">stmt.return</A>],
14.3 [<A href="https://wg21.link/except.ctor">except.ctor</A>])</INS> or at the end of the enclosing
full-expression<INS>; parameters are always destroyed in the reverse
order of their construction.</INS> The initialization and destruction
of each parameter occurs within the context of the full-expression
(6.9.1 [<A href="https://wg21.link/intro.execution">intro.execution</A>]) where the function call appears.

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 8.8 [<A href="https://wg21.link/stmt.dcl#2">stmt.dcl</A>] paragraph 2 as follows:</P>

<BLOCKQUOTE>

A <INS>block</INS> variable with automatic storage duration
(6.7.5.4 [<A href="https://wg21.link/basic.stc.auto">basic.stc.auto</A>]) is active everywhere in the scope to
which it belongs after its <I>init-declarator</I> . Upon each transfer
of control (including sequential execution of statements) within a
function from point P to point Q, all <INS>block</INS> variables with
automatic storage duration that are active at P and not at Q are
destroyed in the reverse order of their construction. Then, all
<INS>block</INS> variables with automatic storage duration that are
active at Q but not at P are initialized in declaration order; unless
all such variables have vacuous initialization
(6.7.3 [<A href="https://wg21.link/basic.life">basic.life</A>]), the transfer of control shall not be a
jump. [ Footnote: ... ] When a <I>declaration-statement</I> is
executed, P and Q are the points immediately before and after it; when
a function returns, Q is after its body.

</BLOCKQUOTE>
</LI>

</OL>

<BR><BR><HR>
<A NAME="2851"></A><H4>2851.
  
Allow floating-point conversions in converted constant expressions
</H4>
<B>Section: </B>7.7&#160; [<A href="https://wg21.link/expr.const">expr.const</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Brian Bi
 &#160;&#160;&#160;

 <B>Date: </B>2023-11-03


<P>(From submission
<A HREF="https://github.com/cplusplus/CWG/issues/456">#456</A>.)</P>

<P>With the adoption of P1907R1, non-type template parameters of
floating-point types have been introduced.  It is surprising that
a <TT>double</TT> value cannot be passed as a template argument for a
template parameter of type <TT>long double</TT>, because
floating-point conversions are not allowed in converted constant
expressions.</P>

<P><B>Proposed resolution (approved by CWG 2024-02-16):</B></P>

<P>Change in 7.7 [<A href="https://wg21.link/expr.const#12">expr.const</A>] paragraph 12 as follows:</P>

<BLOCKQUOTE>

A <I>converted constant expression</I> of type T is an expression,
implicitly converted to type T, where the converted expression is a
constant expression and the implicit conversion sequence contains only
<UL>
<LI>user-defined conversions,</LI>
<LI>lvalue-to-rvalue conversions (7.3.2 [<A href="https://wg21.link/conv.lval">conv.lval</A>]),</LI>
<LI>array-to-pointer conversions (7.3.3 [<A href="https://wg21.link/conv.array">conv.array</A>]),</LI>
<LI>function-to-pointer conversions (7.3.4 [<A href="https://wg21.link/conv.func">conv.func</A>]),</LI>
<LI>qualification conversions (7.3.6 [<A href="https://wg21.link/conv.qual">conv.qual</A>]),</LI>
<LI>integral promotions (7.3.7 [<A href="https://wg21.link/conv.prom">conv.prom</A>]),</LI>
<LI>integral
conversions (7.3.9 [<A href="https://wg21.link/conv.integral">conv.integral</A>]) other than narrowing
conversions (9.4.5 [<A href="https://wg21.link/dcl.init.list">dcl.init.list</A>]),</LI>
<LI class="ins">floating-point promotions (7.3.8 [<A href="https://wg21.link/conv.fpprom">conv.fpprom</A>]),</LI>
<LI class="ins">floating-point conversions
(7.3.10 [<A href="https://wg21.link/conv.double">conv.double</A>]) where the source value can be
represented exactly in the destination type,</LI>
<LI>null pointer
conversions (7.3.12 [<A href="https://wg21.link/conv.ptr">conv.ptr</A>]) from std::nullptr_t,</LI>
<LI>
null member pointer conversions (7.3.13 [<A href="https://wg21.link/conv.mem">conv.mem</A>]) from
std::nullptr_t, and</LI>
<LI>function pointer conversions
(7.3.14 [<A href="https://wg21.link/conv.fctptr">conv.fctptr</A>]),</LI>
</UL>
and where the reference binding (if any) binds directly.

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2853"></A><H4>2853.
  
Pointer arithmetic with pointer to hypothetical element
</H4>
<B>Section: </B>7.6.6&#160; [<A href="https://wg21.link/expr.add">expr.add</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Jim X
 &#160;&#160;&#160;

 <B>Date: </B>2024-02-03


<P>(From submission
<A HREF="https://github.com/cplusplus/CWG/issues/495">#495</A>.)</P>

<P>The phrasing in 7.6.6 [<A href="https://wg21.link/expr.add#4.2">expr.add</A>] bullet 4.2 excludes
pointer arithmetic on a pointer pointing to the hypothetical
(past-the-end) array element.</P>

<P><B>Proposed resolution (approved by CWG 2024-02-16):</B></P>

<P>Change in 7.6.6 [<A href="https://wg21.link/expr.add#4.2">expr.add</A>] bullet 4.2 as follows:</P>

<BLOCKQUOTE>

<UL>
<LI>...</LI>
<LI>
Otherwise, if P points to <DEL>an</DEL> <INS>a
(possibly-hypothetical)</INS> array element i of an array object x
with n elements (9.3.4.5 [<A href="https://wg21.link/dcl.array">dcl.array</A>]), [ Footnote: ... ] the
expressions P + J and J + P (where J has the value j) point to the
(possibly-hypothetical) array element i + j of x if 0 &lt;= i + j
&lt;= n and the expression P - J points to the (possibly-hypothetical)
array element i - j of x if 0 &lt;= i - j &lt;= n.
</LI>
</UL>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2854"></A><H4>2854.
  
Storage duration of exception objects
</H4>
<B>Section: </B>14.2&#160; [<A href="https://wg21.link/except.throw">except.throw</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Jiang An
 &#160;&#160;&#160;

 <B>Date: </B>2024-01-22


<P>(From submission
<A HREF="https://github.com/cplusplus/CWG/issues/492">#492</A>.)</P>

<P>According to 14.2 [<A href="https://wg21.link/except.throw#3">except.throw</A>] paragraph 3, the exception
object is a temporary object.  But none of the possible storage
durations of temporary objects matches the behavior of exception
objects.</P>

<P><B>Proposed resolution (approved by CWG 2024-02-16):</B></P>

<OL>
<LI>
<P>Change in 6.7.7 [<A href="https://wg21.link/class.temporary#1">class.temporary</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

Temporary objects are created
<UL>
<LI>when a prvalue is converted to an xvalue (7.3.5 [<A href="https://wg21.link/conv.rval">conv.rval</A>])<DEL>,</DEL> <INS>and</INS>
</LI>
<LI>when needed by the implementation to pass or return an object of
trivially copyable type (see below)<DEL>, and</DEL><INS>.</INS>
</LI>
<LI class="del">when throwing an exception
(14.2 [<A href="https://wg21.link/except.throw">except.throw</A>]).  [<I>Note 1:</I> The lifetime of
exception objects is described in
14.2 [<A href="https://wg21.link/except.throw">except.throw</A>]. &#8212;<I>end note</I>]</LI>
</UL>
...

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 14.2 [<A href="https://wg21.link/except.throw#3">except.throw</A>] paragraph 3 as follows:</P>

<BLOCKQUOTE>

Throwing an exception initializes <DEL>a temporary</DEL> <INS>an</INS>
object <INS>with dynamic storage duration</INS>, called the exception
object. If the type of the exception object would be an incomplete
type (6.8.1 [<A href="https://wg21.link/basic.types.general">basic.types.general</A>]), an abstract class type
(11.7.4 [<A href="https://wg21.link/class.abstract">class.abstract</A>]), or a pointer to an incomplete type
other than cv void (6.8.4 [<A href="https://wg21.link/basic.compound">basic.compound</A>]) the program is
ill-formed.

</BLOCKQUOTE>
</LI>
</OL>

<BR><BR><HR>
<A NAME="2855"></A><H4>2855.
  
Undefined behavior in postfix increment
</H4>
<B>Section: </B>7.6.1.6&#160; [<A href="https://wg21.link/expr.post.incr">expr.post.incr</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>L&#233;n&#225;rd Szolnoki
 &#160;&#160;&#160;

 <B>Date: </B>2023-12-12


<P>(From submission
<A HREF="https://github.com/cplusplus/CWG/issues/479">#479</A>.)</P>

<P>Consider:</P>

<PRE>
  int8_t x = 127;
  x++;
</PRE>

<P>This has undefined behavior, because the resulting value is not
representable as an <TT>int8_t</TT>.  In contrast,</P>

<PRE>
  int8_t x = 127;
  ++x;
</PRE>

<P>is well-defined, because it is equivalent to <TT>x += 1</TT>, which
is equivalent to <TT>x = (int)x + 1</TT> after the usual arithmetic
conversions (7.4 [<A href="https://wg21.link/expr.arith.conv">expr.arith.conv</A>]).  No arithmetic overflow
occurs.  The presence or absence of undefined behavior is detectable
in constant evaluation.</P>

<P><B>Proposed resolution (approved by CWG 2024-02-16):</B></P>

<OL>
<LI>
<P>Change in 7.6.1.6 [<A href="https://wg21.link/expr.post.incr#1">expr.post.incr</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

The value of a postfix ++ expression is the value of its operand.
[<I>Note 1:</I> The value obtained is a copy of the original
value. &#8212;<I>end note</I>]  The operand shall be a modifiable
lvalue. The type of the operand shall be an arithmetic type other than
cv bool, or a pointer to a complete object type. An operand with
volatile-qualified type is deprecated; see D.4 [<A href="https://wg21.link/depr.volatile.type">depr.volatile.type</A>].
The value of the operand object is modified (3.1 [<A href="https://wg21.link/defns.access">defns.access</A>])
<DEL>by adding 1 to it</DEL> <INS>as if it were the operand of the
prefix <TT>++</TT> operator (7.6.2.3 [<A href="https://wg21.link/expr.pre.incr">expr.pre.incr</A>]).</INS> The
value computation of the ++ expression is sequenced before the
modification of the operand object. With respect to an
indeterminately-sequenced function call, the operation of postfix ++
is a single evaluation.  [<I>Note 2:</I> Therefore, a function call
cannot intervene between the lvalue-to-rvalue conversion and the side
effect associated with any single postfix ++ operator. &#8212;<I>end
note</I>] The result is a prvalue. The type of the result is the
cv-unqualified version of the type of the operand. <DEL>If the operand
is a bit-field that cannot represent the incremented value, the
resulting value of the bit-field is implementation-defined. See also
7.6.6 [<A href="https://wg21.link/expr.add">expr.add</A>] and 7.6.19 [<A href="https://wg21.link/expr.ass">expr.ass</A>].</DEL>

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 7.6.2.3 [<A href="https://wg21.link/expr.pre.incr">expr.pre.incr</A>] as follows:</P>

<BLOCKQUOTE>

<P>The operand of prefix <TT>++</TT> <INS>or <TT>--</TT></INS> <DEL>is
modified (3.1 [<A href="https://wg21.link/defns.access">defns.access</A>]) by adding 1. The operand shall be
a modifiable lvalue. The type of the operand</DEL>
shall <INS>not</INS> be <DEL>an arithmetic type other
than</DEL> <INS>of type</INS> <I>cv</I> <TT>bool</TT><DEL>, or a
pointer to a completely-defined object type</DEL>. An operand with
volatile-qualified type is deprecated; see D.4 [<A href="https://wg21.link/depr.volatile.type">depr.volatile.type</A>].
<DEL>The result is the updated operand; it is an lvalue, and it is a
bit-field if the operand is a bit-field.</DEL> The
expression <TT>++x</TT> is <INS>otherwise</INS> equivalent to
x+=1 <INS>and the expression <TT>--x</TT> is otherwise equivalent
to <TT>x-=1</TT></INS> <DEL>. [<I>Note 1:</I> See the discussions of
addition (7.6.6 [<A href="https://wg21.link/expr.add">expr.add</A>]) and assignment operators</DEL>
(7.6.19 [<A href="https://wg21.link/expr.ass">expr.ass</A>]) <DEL>for information on conversions</DEL>.
<DEL>&#8212;<I>end note</I>]</DEL>
</P>

<P>
<DEL>The operand of prefix -- is modified
(3.1 [<A href="https://wg21.link/defns.access">defns.access</A>]) by subtracting 1. The requirements on the
operand of prefix -- and the properties of its result are otherwise
the same as those of prefix ++.</DEL> [<I>Note 2:</I> For postfix
increment and decrement, see
7.6.1.6 [<A href="https://wg21.link/expr.post.incr">expr.post.incr</A>]. &#8212;<I>end note</I>]
</P>

</BLOCKQUOTE>
</LI>

</OL>

<BR><BR><HR>
<A NAME="2856"></A><H4>2856.
  
Copy-list-initialization with explicit default constructors
</H4>
<B>Section: </B>12.2.2.8&#160; [<A href="https://wg21.link/over.match.list">over.match.list</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Anoop Rana
 &#160;&#160;&#160;

 <B>Date: </B>2024-01-09


<P>(From submission
<A HREF="https://github.com/cplusplus/CWG/issues/486">#486</A>.)</P>

<P>Consider:</P>

<PRE>
  struct A {
     explicit A(int = 10);
     A() = default;   // <SPAN CLASS="cmnt">converting constructor (11.4.8.2 [<A href="https://wg21.link/class.conv.ctor#1">class.conv.ctor</A>] paragraph 1)</SPAN>
  };

  A a = {};       // <SPAN CLASS="cmnt">#1, copy-initialization</SPAN>
  
  int f(A);
  int x = f({});  // <SPAN CLASS="cmnt">#2</SPAN>

  A b;            // <SPAN CLASS="cmnt">#3</SPAN>
</PRE>

<P>#1 and #2 are accepted by MSVC and EDG, but considered ambiguous by
gcc and clang.  #3 is rejected as ambiguous by all major
implementations.</P>

<P>#1 is copy-list-initialization (9.4.5 [<A href="https://wg21.link/dcl.init.list#1">dcl.init.list</A>] paragraph 1), and <TT>A</TT> has a default constructor, thus <TT>a</TT>
is value-initialized (9.4.5 [<A href="https://wg21.link/dcl.init.list#3.4">dcl.init.list</A>] bullet 3.4).  The
default constructors are user-provided, thus <TT>a</TT> is
default-initialized (9.4.1 [<A href="https://wg21.link/dcl.init.general#8.1">dcl.init.general</A>] bullet 8.1,
9.4.1 [<A href="https://wg21.link/dcl.init.general#7.1">dcl.init.general</A>] bullet 7.1).  Overload resolution then
chooses a constructor according to 12.2.2.4 [<A href="https://wg21.link/over.match.ctor#1">over.match.ctor</A>] paragraph 1:</P>

<BLOCKQUOTE>

... For copy-initialization (including default initialization in the
context of copy-initialization), the candidate functions are all the
converting constructors (11.4.8.2 [<A href="https://wg21.link/class.conv.ctor">class.conv.ctor</A>]) of that class. ...

</BLOCKQUOTE>

<P>Thus, the explicit constructor is not a candidate; #1 chooses the
converting constructor.</P>

<P>In contrast, #2 uses the special rules for forming a
list-initialization sequence (12.2.4.2.6 [<A href="https://wg21.link/over.ics.list#7">over.ics.list</A>] paragraph 7), which perform overload resolution according to
12.2.2.8 [<A href="https://wg21.link/over.match.list#1">over.match.list</A>] paragraph 1, which considers all
constructors for overload resolution (and makes the program ill-formed
if an explicit constructor is chosen).  For the example, overload
resolution is ambiguous.</P>

<P>#3 performs default-initialization, and overload resolution then
chooses a constructor according to 12.2.2.4 [<A href="https://wg21.link/over.match.ctor#1">over.match.ctor</A>] paragraph 1:</P>

<BLOCKQUOTE>

... For direct-initialization or default-initialization that is not in the
context of copy-initialization, the candidate functions are all the
constructors of the class of the object being initialized. ...

</BLOCKQUOTE>

<P>In this case, the overload resolution is ambiguous.</P>

<P><B>Proposed resolution (approved by CWG 2024-02-16):</B></P>

<P>Change in 12.2.2.4 [<A href="https://wg21.link/over.match.ctor#1">over.match.ctor</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

When objects of class type are direct-initialized
(9.4 [<A href="https://wg21.link/dcl.init">dcl.init</A>]), copy-initialized from an expression of the
same or a derived class type (9.4 [<A href="https://wg21.link/dcl.init">dcl.init</A>]), or
default-initialized (9.4 [<A href="https://wg21.link/dcl.init">dcl.init</A>]), overload resolution
selects the constructor. For direct-initialization or
default-initialization <DEL>that is not in the context of
copy-initialization</DEL> <INS>(including default-initialization in
the context of copy-list-initialization)</INS>, the candidate
functions are all the constructors of the class of the object being
initialized. <DEL>For copy-initialization (including default
initialization in the context of
copy-initialization)</DEL> <INS>Otherwise</INS>, the candidate
functions are all the converting constructors
(11.4.8.2 [<A href="https://wg21.link/class.conv.ctor">class.conv.ctor</A>]) of that class. The argument list is
the <I>expression-list</I> or <I>assignment-expression</I> of the
initializer. <INS>For default-initialization in the context of
copy-list-initialization, if an explicit constructor is chosen, the
initialization is ill-formed.</INS>

</BLOCKQUOTE>

<P><B>CWG 2024-02-16</B></P>

<P>The fact that #2 considers all constructors was discussed (and
established) in the C++11 timeframe when brace-initialization was
first introduced.  #1 should be consistent with that, even though
the <TT>=</TT> is usually a clear sign that explicit constructors are
not considered.</P>

<BR><BR><HR>
<A NAME="2857"></A><H4>2857.
  
Argument-dependent lookup with incomplete class types
</H4>
<B>Section: </B>6.5.4&#160; [<A href="https://wg21.link/basic.lookup.argdep">basic.lookup.argdep</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Lewis Baker
 &#160;&#160;&#160;

 <B>Date: </B>2024-02-08




<P>Subclause 6.5.4 [<A href="https://wg21.link/basic.lookup.argdep#3.2">basic.lookup.argdep</A>] bullet 3.2 specifies:</P>

<BLOCKQUOTE>

<UL>
<LI>...</LI>
<LI>If T is a class type (including unions), its associated entities are:
the class itself; the class of which it is a member, if any; and its
direct and indirect base classes. ...</LI>
<LI>...</LI>
</UL>

</BLOCKQUOTE>

<P>It is unclear what happens if <TT>T</TT> is incomplete, for example
because it was instantiated from a template whose definition was not
(yet) available.</P>

<P><B>Proposed resolution (approved by CWG 2024-03-01)</B></P>

<P>Change in 6.5.4 [<A href="https://wg21.link/basic.lookup.argdep#3.2">basic.lookup.argdep</A>] bullet 3.2 as follows:</P>

<BLOCKQUOTE>

<UL>
<LI>...</LI>
<LI>If T is a class type (including unions), its associated entities
are: the class itself; the class of which it is a member, if any;
and<INS>, if it is a complete type,</INS> its direct and indirect base
classes. ...</LI>
<LI>...</LI>
</UL>

</BLOCKQUOTE>


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