<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;P3345R0</TD>
</TR>
<TR>
<TD ALIGN="RIGHT">
      Date:
     </TD>
<TD>
      &#160;2024-06-28</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
     June, 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/2024/n4981.pdf">WG21 N4981</A>.
   </P>
<HR>
<A NAME="233"></A><H4>233.
  
References vs pointers in UDC overload resolution
</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>Matthias Meixner
 &#160;&#160;&#160;

 <B>Date: </B>9 Jun 2000


<P>There is an inconsistency in the handling of references
vs pointers in user defined conversions and overloading. The reason
for that is that the combination of 9.4.4 [<A href="https://wg21.link/dcl.init.ref">dcl.init.ref</A>] and
7.3.6 [<A href="https://wg21.link/conv.qual">conv.qual</A>] circumvents the standard way of ranking
conversion functions, which was probably not the intention of the
designers of the standard.</P>

<P>Let's start with some examples, to show what it is about:</P>

<PRE>
    struct Z { Z(){} };

    struct A {
       Z x;

       operator Z *() { return &amp;x; }
       operator const Z *() { return &amp;x; }
    };

    struct B {
       Z x;

       operator Z &amp;() { return x; }
       operator const Z &amp;() { return x; }
    };

    int main()
    {
       A a;
       Z *a1=a;
       const Z *a2=a; // not ambiguous

       B b;
       Z &amp;b1=b;
       const Z &amp;b2=b; // ambiguous
    }
</PRE>

<P>So while both classes <TT>A</TT> and <TT>B</TT> are structurally
equivalent, there is a difference in operator overloading. I want to
start with the discussion of the pointer case (<TT>const Z
*a2=a;</TT>): 12.2.4 [<A href="https://wg21.link/over.match.best">over.match.best</A>] is used to select the best
viable function. Rule 4 selects <TT>A::operator const Z*()</TT> as
best viable function using 12.2.4.3 [<A href="https://wg21.link/over.ics.rank">over.ics.rank</A>] since the
implicit conversion sequence <TT>const Z*</TT> -&gt; <TT>const Z*</TT>
is a better conversion sequence than <TT>Z*</TT> -&gt; <TT>const
Z*</TT>.</P>

<P>So what is the difference to the reference case?  Cv-qualification
conversion is only applicable for pointers according to 7.3.6 [<A href="https://wg21.link/conv.qual">conv.qual</A>]. According to 9.4.4 [<A href="https://wg21.link/dcl.init.ref">dcl.init.ref</A>] paragraphs
4-7 references are initialized by binding using the concept of
reference-compatibility. The problem with this is, that in this
context of binding, there is no conversion, and therefore there is
also no comparing of conversion sequences. More exactly all
conversions can be considered identity conversions according to
12.2.4.2.5 [<A href="https://wg21.link/over.ics.ref#1">over.ics.ref</A>] paragraph 1, which compare equal
and which has the same effect.  So binding <TT>const Z*</TT> to
<TT>const Z*</TT> is as good as binding <TT>const Z*</TT> to
<TT>Z*</TT> in terms of overloading. Therefore <TT>const Z
&amp;b2=b;</TT> is ambiguous.  [12.2.4.2.5 [<A href="https://wg21.link/over.ics.ref#5">over.ics.ref</A>] paragraph 5
and 12.2.4.3 [<A href="https://wg21.link/over.ics.rank#3">over.ics.rank</A>] paragraph 3 rule 3
(S1 and S2 are reference bindings ...) do not seem to apply to this
case]</P>

<P>There are other ambiguities, that result in the special treatment
of references: Example:</P>

<PRE>
    struct A {int a;};
    struct B: public A { B() {}; int b;};

    struct X {
       B x;
       operator A &amp;() { return x; }
       operator B &amp;() { return x; }
    };

    main()
    {
       X x;
       A &amp;g=x; // ambiguous
    }
</PRE>

<P>Since both references of class <TT>A</TT> and <TT>B</TT> are
reference compatible with references of class <TT>A</TT> and since
from the point of ranking of implicit conversion sequences they are
both identity conversions, the initialization is ambiguous.
</P>

<P>So why should this be a defect?</P>

<UL>

<LI>References behave fundamentally different from pointers in combination
with user defined conversions, although there is no reason to have this
different treatment.</LI>

<LI>This difference only shows up in combination with user defined
conversion sequences, for all other cases, there are special rules,
e.g. 12.2.4.3 [<A href="https://wg21.link/over.ics.rank#3">over.ics.rank</A>] paragraph 3 rule 3.</LI>

</UL>

<P>So overall I think this was not the intention of the authors of the
standard.</P>

<P>So how could this be fixed? For comparing conversion sequences (and
only for comparing) reference binding should be treated as if it was a
normal assignment/initialization and cv-qualification would have to be
defined for references. This would affect 9.4.4 [<A href="https://wg21.link/dcl.init.ref#6">dcl.init.ref</A>] paragraph 6, 7.3.6 [<A href="https://wg21.link/conv.qual">conv.qual</A>] and probably
12.2.4.3 [<A href="https://wg21.link/over.ics.rank#3">over.ics.rank</A>] paragraph 3.</P>

<P>Another fix could be to add a special case in 12.2.4 [<A href="https://wg21.link/over.match.best#1">over.match.best</A>] paragraph 1. </P>

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

<P>It was noted that the second example is not ambiguous, because a
derived-to-base conversion is compared against an identity conversion.
However, 12.2.4.2.5 [<A href="https://wg21.link/over.ics.ref#1">over.ics.ref</A>] paragraph 1 needs a wording fix
so that it applies to conversion functions as well.  CWG opined that
the first example be made valid, by adding a missing tie-breaker for
the conversion function case.</P>

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

<OL>
<LI>
<P>Change in 12.2.4.1 [<A href="https://wg21.link/over.match.best.general#2.2">over.match.best.general</A>] bullet 2.2 as follows:</P>

<BLOCKQUOTE>

<UL>
<LI>...</LI>
<LI>the context is an initialization by user-defined conversion (see
9.4 [<A href="https://wg21.link/dcl.init">dcl.init</A>], 12.2.2.6 [<A href="https://wg21.link/over.match.conv">over.match.conv</A>], and
12.2.2.7 [<A href="https://wg21.link/over.match.ref">over.match.ref</A>]) and the standard conversion sequence
from the <DEL>return type</DEL> <INS>result</INS> of F1 to the
destination type (i.e., the type of the entity being initialized) is a
better conversion sequence than the standard conversion sequence from
the <DEL>return type</DEL> <INS>result</INS> of F2 to the destination
type</LI>
<LI>...</LI>
</UL>

</BLOCKQUOTE>
</LI>

<LI>
<P>Add a new sub-bullet to 12.2.4.3 [<A href="https://wg21.link/over.ics.rank#3.2">over.ics.rank</A>] bullet 3.2
as follows:</P>

<BLOCKQUOTE>

<UL>
<LI>...</LI>
<LI>S1 and S2 include reference bindings (9.4.4 [<A href="https://wg21.link/dcl.init.ref">dcl.init.ref</A>]), 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>.</DEL>
[ Example: ... -- end example ]
<INS>or, if not that,</INS>
</LI>

<LI class="ins">
<TT>S1</TT> and <TT>S2</TT> bind the same reference type "reference to
<TT>T</TT>" and have source types <TT>V1</TT> and <TT>V2</TT>,
respectively, where the standard conversion sequence from <TT>V1*</TT>
to <TT>T*</TT> is better than the standard conversion sequence
from <TT>V2*</TT> to <TT>T*</TT>.  [ Example:
<PRE>
  struct Z {};

  struct A {
    operator Z&amp;();
    operator const Z&amp;();       // <SPAN CLASS="cmnt">#1</SPAN>
  };

  struct B {
    operator Z();
    operator const Z&amp;&amp;();      // <SPAN CLASS="cmnt">#2</SPAN>
  };

  const Z&amp; r1 = A();          // <SPAN CLASS="cmnt">OK, uses #1</SPAN>
  const Z&amp;&amp; r2 = B();         // <SPAN CLASS="cmnt">OK, uses #2</SPAN>
</PRE>
--- end example]
</LI>
</UL>

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

<BR><BR><HR>
<A NAME="2144"></A><H4>2144.
  
Function/variable declaration ambiguity
</H4>
<B>Section: </B>9.5.1&#160; [<A href="https://wg21.link/dcl.fct.def.general">dcl.fct.def.general</A>]
 &#160;&#160;&#160;

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

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

 <B>Date: </B>2015-06-19




<P>The following fragment,</P>

<PRE>
  int f() {};
</PRE>

<P>is syntactically ambiguous.  It could be either a
<I>function-definition</I> followed by an <I>empty-declaration</I>,
or it could be a <I>simple-declaration</I> whose
<I>init-declarator</I> has the <I>brace-or-equal-initializer</I>
<TT>{}</TT>.  The same is true of a variable declaration</P>

<PRE>
  int a {};
</PRE>

<P>since <I>function-definition</I> simply uses the
term <I>declarator</I> in its production.</P>

<P><B>Additional notes (May, 2024)</B></P>

<P>Issue 2876 introduced a framework to
distinguish the parsing.  Its resolution was extended to also resolve
this issue.</P>
<BR><BR><HR>
<A NAME="2561"></A><H4>2561.
  
Conversion to function pointer for lambda with explicit object parameter
</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>2022-02-14




<P>P0847R7 (Deducing this) (approved October, 2021) added
explicit-object member functions. Consider:</P>

<PRE>
  struct C {
    C(auto) { }
  };

  void foo() {
    auto l = [](this C) { return 1; };
    void (*fp)(C) = l;
    fp(1); //<SPAN CLASS="cmnt"> same effect as </SPAN>decltype(l){}()<SPAN CLASS="cmnt"> or </SPAN>decltype(l){}(1)<SPAN CLASS="cmnt"> ?</SPAN>
  }
</PRE>

<P>Subclause 7.5.5.2 [<A href="https://wg21.link/expr.prim.lambda.closure#8">expr.prim.lambda.closure</A>] paragraph 8 does not address
explicit object member functions:</P>

<BLOCKQUOTE>

The closure type for a non-generic <I>lambda-expression</I> with
no <I>lambda-capture</I> whose constraints (if any) are satisfied has
a conversion function to pointer to function with C++ language linkage
(9.11 [<A href="https://wg21.link/dcl.link">dcl.link</A>]) having the same parameter and return types
as the closure type's function call operator. The conversion is to
&#8220;pointer to noexcept function&#8221; if the function call
operator has a non-throwing exception specification. The value
returned by this conversion function is the address of a function F
that, when invoked, has the same effect as invoking the closure type's
function call operator on a default-constructed instance of the
closure type. F is a constexpr function if...

</BLOCKQUOTE>

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

<OL>

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

<BLOCKQUOTE>

... The value returned by this conversion function is

<UL>

<LI><INS>for a <I>lambda-expression</I>
whose <I>parameter-declaration-clause</I> has an explicit object
parameter, the address of the function call operator
(7.6.2.2 [<A href="https://wg21.link/expr.unary.op">expr.unary.op</A>];</INS></LI>

<LI>
<INS>otherwise,</INS> the address of a
function F that, when invoked, has the same effect as invoking the
closure type's function call operator on a default-constructed
instance of the closure type.</LI>

</UL>

F is a constexpr function if... is an immediate function.

<P><INS>[ <I>Example</I>:</INS></P>

<PRE>
  struct C {
    C(auto) { }
  };

  void foo() {
    auto a = [](C) { return 0; };
    int (*fp)(C) = a;   // OK
    fp(1);              //<SPAN CLASS="cmnt"> same effect as </SPAN>decltype(a){}(1)
    auto b = [](this C) { return 1; };
    fp = b;             // OK
    fp(1);              //<SPAN CLASS="cmnt"> same effect as </SPAN>(&amp;decltype(b)::operator())(1)
  }
</PRE>

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

</BLOCKQUOTE>
</LI>

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

<BLOCKQUOTE>

The value returned by any given specialization of this conversion
function template is

<UL>
<LI>
<INS>for a <I>lambda-expression</I>
whose <I>parameter-declaration-clause</I> has an explicit object
parameter, the address of the corresponding function call operator
template specialization (7.6.2.2 [<A href="https://wg21.link/expr.unary.op">expr.unary.op</A>]);</INS>
</LI>

<LI>
<INS>otherwise,</INS> the address of a function F that, when invoked,
has the same effect as invoking the generic lambda's corresponding
function call operator template specialization on a
default-constructed instance of the closure type.
</LI>
</UL>

F is a constexpr function if...

</BLOCKQUOTE>

</LI>

</OL>

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

<P>
Requesting guidance from EWG with
<A HREF="https://github.com/cplusplus/papers/issues/1689">paper issue 1689</A>.</P>

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

<P>Additional examples demonstrating implementation divergence between clang
and MSVC:</P>

<PRE>
  struct Any { Any(auto) {} };
  auto x = [](this auto self, int x) { return x; };
  auto y = [](this Any self, int x) { return x; };
  auto z = [](this int (*self)(int), int x) { return x; };
  int main() {
    x(1);
    y(1);
    z(1);
    int (*px)(int) = +x; //<SPAN CLASS="cmnt"> MSVC</SPAN>
    int (*py1)(int) = +y; //<SPAN CLASS="cmnt"> MSVC</SPAN>
    int (*py2)(Any, int) = +y; //<SPAN CLASS="cmnt"> Clang</SPAN>
    int (*pz1)(int) = +z; //<SPAN CLASS="cmnt"> MSVC</SPAN>
    int (*pz2)(int (*)(int), int) = +z; //<SPAN CLASS="cmnt"> Clang</SPAN>
  }
</PRE>

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

<P>Additional example:</P>

<PRE>
  auto c2 = [](this auto self) { return sizeof(self); };
  struct Derived2 : decltype(c) { int value; } d2;
  struct Derived3 : decltype(c) { int value[10]; } d3;
</PRE>

<P>For MSVC, <TT>d2() == 4</TT> and <TT>d3() == 40</TT>,
but <TT>+d2</TT> and <TT>+d3</TT> both point to functions
returning <TT>1</TT>.</P>

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

<P>Move forward with option 1 "punt" from D3031 for C++26.
A future paper can explore other solutions.</P>

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

<OL>
<LI>
<P>Change the example in 7.5.5.1 [<A href="https://wg21.link/expr.prim.lambda.general#6">expr.prim.lambda.general</A>] paragraph 6 as follows:</P>

<PRE>
<DEL>  int i = [](int i, auto a) { return i; }(3, 4);  //<SPAN CLASS="cmnt"> OK, a generic lambda</SPAN>
  int j = []&lt;class T&gt;(T t, int i) { return i; }(3, 4);  //<SPAN CLASS="cmnt"> OK, a generic lambda</SPAN></DEL>
<INS>  auto x = [](int i, auto a) { return i; };             //<SPAN CLASS="cmnt"> OK, a generic lambda</SPAN>
  auto y = [](this auto self, int i) { return i; };      //<SPAN CLASS="cmnt"> OK, a generic lambda</SPAN>
  auto z = []&lt;class T&gt;(int i) { return i; };             //<SPAN CLASS="cmnt"> OK, a generic lambda</SPAN>
</INS>
</PRE>
</LI>

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

<BLOCKQUOTE>

The closure type for a non-generic <I>lambda-expression</I> with
no <I>lambda-capture</I> <INS>and no explicit object parameter
(9.3.4.6 [<A href="https://wg21.link/dcl.fct">dcl.fct</A>])</INS> whose constraints (if any) are
satisfied has a conversion function to pointer to function with C++
language linkage (9.11 [<A href="https://wg21.link/dcl.link">dcl.link</A>]) having the same parameter
and return types as the closure type's function call operator. ...

</BLOCKQUOTE>
</LI>

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

<BLOCKQUOTE>

For a generic lambda with no <I>lambda-capture</I> <INS>and no
explicit object parameter (9.3.4.6 [<A href="https://wg21.link/dcl.fct">dcl.fct</A>])</INS>, the
closure type has a conversion function template to pointer to
function. ...

</BLOCKQUOTE>
</LI>

</OL>

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

<P>Keeping in review status in anticipation of a paper proposing
reasonable semantics for the function pointer conversions.</P>

<P><B>EWG 2024-03-18</B></P>

<P>Progress with option #1 of
<A HREF="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p3031r0.html">P3031R0</A>,
affirming the direction of the proposed resolution.</P>

<BR><BR><HR>
<A NAME="2588"></A><H4>2588.
  
friend declarations and module linkage
</H4>
<B>Section: </B>11.8.4&#160; [<A href="https://wg21.link/class.friend">class.friend</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Nathan Sidwell
 &#160;&#160;&#160;

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


<P>Consider:</P>

<PRE>
  export module Foo;
  class X {
    friend void f(X); //<SPAN CLASS="cmnt"> #1 linkage?</SPAN>
  };
</PRE>

<P>Subclause 11.8.4 [<A href="https://wg21.link/class.friend#4">class.friend</A>] paragraph 4 gives #1 external linkage:
</P>

<BLOCKQUOTE>

A function first declared in a friend declaration has the linkage of
the namespace of which it is a member (6.6 [<A href="https://wg21.link/basic.link">basic.link</A>]).

</BLOCKQUOTE>

<P>(There is no similar provision for friend classes first declared in
a class.)</P>

<P>However, 6.6 [<A href="https://wg21.link/basic.link#4.8">basic.link</A>] bullet 4.8 gives it 
module linkage:</P>

<BLOCKQUOTE>

... otherwise, if the declaration of the name is attached to a named
module (10.1 [<A href="https://wg21.link/module.unit">module.unit</A>]) and is not exported
(10.2 [<A href="https://wg21.link/module.interface">module.interface</A>]), the name has module linkage;

</BLOCKQUOTE>

<P>Subclause 10.2 [<A href="https://wg21.link/module.interface#2">module.interface</A>] paragraph 2 does not apply:</P>

<BLOCKQUOTE>

A declaration is <I>exported</I> if it is declared within
an <I>export-declaration</I> and inhabits a namespace scope or it is

<UL>
<LI>a <I>namespace-definition</I> that contains an exported
declaration, or
</LI>

<LI>a declaration within a header unit
(10.3 [<A href="https://wg21.link/module.import">module.import</A>]) that introduces at least one name.
</LI>
</UL>

</BLOCKQUOTE>

<P>Also consider this related example:</P>

<PRE>
  export module Foo;
  export class Y;
  //<SPAN CLASS="cmnt"> maybe many lines later, or even a different partition of Foo</SPAN>
  class Y {
    friend void f(Y); //<SPAN CLASS="cmnt"> #2 linkage?</SPAN>
  };
</PRE>

<UL>
<LI>Should the friend's linkage be affected by the linkage of the
befriending class?  In this example, #2 would therefore have external
linkage, as <TT>Y</TT> is exported.</LI>

<LI>Or should the friend's linkage be affected by the presence or
absence of <TT>export</TT> on the class definition itself? In this
example, #2 would thus have module linkage.</LI>

<LI>Or should the friend's linkage be determined ignoring any
enclosing <TT>export</TT> and ignoring whether the enclosing class is
exported, per 11.8.4 [<A href="https://wg21.link/class.friend#4">class.friend</A>] paragraph 4 (alone)?</LI>

<LI>Or should the friend's linkage be as-if the declaration inhabited
its nearest enclosing namespace scope, without
the <TT>friend</TT>?</LI>

</UL>

<P>See issue 2607 for a similar question
about enumerators.</P>

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

<P>Forwarded to EWG with
<A HREF="https://github.com/cplusplus/papers/issues/1253">paper issue 1253</A>,
by decision of the CWG chair.
</P>

<P><B>EWG telecon 2022-06-09</B></P>

<P>Consensus: "A friend's linkage should be affected by the
presence/absence of export on the containing class definition itself,
but ONLY if the friend is a definition", pending confirmation by
electronic polling.</P>

<P><B>Proposed resolution (June, 2022) (approved by CWG 2023-01-27) [SUPERSEDED]:</B></P>

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

<BLOCKQUOTE>

... The name of an entity that belongs to a namespace scope that has not
been given internal linkage above and that is the name of

<UL>
<LI>a variable; or</LI>
<LI>a function; or</LI>
<LI>a named class (11.1 [<A href="https://wg21.link/class.pre">class.pre</A>]), or an unnamed class
defined in a typedef declaration in which the class has the typedef
name for linkage purposes (9.2.4 [<A href="https://wg21.link/dcl.typedef">dcl.typedef</A>]); or</LI>
<LI>a named enumeration (9.7.1 [<A href="https://wg21.link/dcl.enum">dcl.enum</A>]), or an unnamed
enumeration defined in a typedef declaration in which the enumeration
has the typedef name for linkage purposes
(9.2.4 [<A href="https://wg21.link/dcl.typedef">dcl.typedef</A>]); or</LI>
<LI>an unnamed
enumeration that has an enumerator as a name for linkage purposes
(9.7.1 [<A href="https://wg21.link/dcl.enum">dcl.enum</A>]); or</LI>
<LI>a template</LI>
</UL>
has its linkage
determined as follows:
<UL>
<LI>
<INS>if the entity is a function or function template first
declared in a friend declaration and that declaration is a definition,
the name has the same linkage, if any, as the name of the enclosing
class (11.8.4 [<A href="https://wg21.link/class.friend">class.friend</A>]);</INS>
</LI>
<LI>
<INS>otherwise, if the entity is a function or function template
declared in a friend declaration and a corresponding non-friend
declaration is reachable, the name has the linkage determined from
that prior declaration,</INS>
</LI>
<LI>
<INS>otherwise,</INS> if the enclosing namespace has internal
linkage, the name has internal linkage;</LI>
<LI>otherwise, if the
declaration of the name is attached to a named module
(10.1 [<A href="https://wg21.link/module.unit">module.unit</A>]) and is not exported
(10.2 [<A href="https://wg21.link/module.interface">module.interface</A>]), the name has module linkage;</LI>
<LI>
otherwise, the name has external linkage.
</LI>
</UL>

</BLOCKQUOTE>
</LI>

<LI>
<P>Remove 11.8.4 [<A href="https://wg21.link/class.friend#4">class.friend</A>] paragraph 4:</P>

<BLOCKQUOTE>

<DEL> A function first declared in a friend declaration has the
linkage of the namespace of which it is a member
(6.6 [<A href="https://wg21.link/basic.link">basic.link</A>]).  Otherwise, the function retains its
previous linkage (9.2.2 [<A href="https://wg21.link/dcl.stc">dcl.stc</A>]).</DEL>

</BLOCKQUOTE>

</LI>
</OL>



<P><B>EWG electronic poll 2022-06</B></P>

<P>Consensus for "A friend's linkage should be affected by the
presence/absence of export on the containing class definition itself,
but ONLY if the friend is a definition (option #2, modified by Jason's
suggestion). This resolves CWG2588."
See
<A HREF="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1018r17.html#CWG2588">vote</A>.</P>

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

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

<BLOCKQUOTE>

... The name of an entity that belongs to a namespace scope that has not
been given internal linkage above and that is the name of

<UL>
<LI>a variable; or</LI>
<LI>a function; or</LI>
<LI>a named class (11.1 [<A href="https://wg21.link/class.pre">class.pre</A>]), or an unnamed class
defined in a typedef declaration in which the class has the typedef
name for linkage purposes (9.2.4 [<A href="https://wg21.link/dcl.typedef">dcl.typedef</A>]); or</LI>
<LI>a named enumeration (9.7.1 [<A href="https://wg21.link/dcl.enum">dcl.enum</A>]), or an unnamed
enumeration defined in a typedef declaration in which the enumeration
has the typedef name for linkage purposes
(9.2.4 [<A href="https://wg21.link/dcl.typedef">dcl.typedef</A>]); or</LI>
<LI>an unnamed
enumeration that has an enumerator as a name for linkage purposes
(9.7.1 [<A href="https://wg21.link/dcl.enum">dcl.enum</A>]); or</LI>
<LI>a template</LI>
</UL>
has its linkage
determined as follows:
<UL>
<LI>
<INS>if the entity is a function or function template first
declared in a friend declaration and that declaration is a definition
and the enclosing class is defined within an <I>export-declaration</I>,
the name has the same linkage, if any, as the name of the enclosing
class (11.8.4 [<A href="https://wg21.link/class.friend">class.friend</A>]);</INS>
</LI>
<LI>
<INS>otherwise, if the entity is a function or function template
declared in a friend declaration and a corresponding non-friend
declaration is reachable, the name has the linkage determined from
that prior declaration,</INS>
</LI>
<LI>
<INS>otherwise,</INS> if the enclosing namespace has internal
linkage, the name has internal linkage;</LI>
<LI>otherwise, if the
declaration of the name is attached to a named module
(10.1 [<A href="https://wg21.link/module.unit">module.unit</A>]) and is not exported
(10.2 [<A href="https://wg21.link/module.interface">module.interface</A>]), the name has module linkage;</LI>
<LI>
otherwise, the name has external linkage.
</LI>
</UL>

</BLOCKQUOTE>
</LI>

<LI>
<P>Remove 11.8.4 [<A href="https://wg21.link/class.friend#4">class.friend</A>] paragraph 4:</P>

<BLOCKQUOTE>

<DEL> A function first declared in a friend declaration has the
linkage of the namespace of which it is a member
(6.6 [<A href="https://wg21.link/basic.link">basic.link</A>]).  Otherwise, the function retains its
previous linkage (9.2.2 [<A href="https://wg21.link/dcl.stc">dcl.stc</A>]).</DEL>

</BLOCKQUOTE>

</LI>
</OL>

<BR><BR><HR>
<A NAME="2728"></A><H4>2728.
  
Evaluation of conversions in a <I>delete-expression</I>
</H4>
<B>Section: </B>7.6.2.9&#160; [<A href="https://wg21.link/expr.delete">expr.delete</A>]
 &#160;&#160;&#160;

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

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

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


<P>Subclause 7.6.2.9 [<A href="https://wg21.link/expr.delete#4">expr.delete</A>] paragraph 4 specifies:</P>

<BLOCKQUOTE>

The <I>cast-expression</I> in a <I>delete-expression</I> shall be
evaluated exactly once.

</BLOCKQUOTE>

<P>Due to the reference to the syntactic
non-terminal <I>cast-expression</I>, it is unclear whether that
includes the conversion to pointer type specified in
7.6.2.9 [<A href="https://wg21.link/expr.delete#2">expr.delete</A>] paragraph 2.</P>

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

<OL>
<LI>
<P>Change in 7.6.2.9 [<A href="https://wg21.link/expr.delete#1">expr.delete</A>] paragraph 1 and paragraph 2 as
follows:</P>

<BLOCKQUOTE>

<P>
... The operand shall be <INS>of class type or a prvalue</INS> of
pointer to object type<DEL> or of class type</DEL>. If of class type,
the operand is contextually implicitly converted
(7.3 [<A href="https://wg21.link/conv">conv</A>]) to a <INS>prvalue</INS> pointer to object
type. [ Footnote: ... ]
<INS>The converted operand is used in place of the original operand
for the remainder of this subclause.</INS>
The <I>delete-expression</I> has type void.
</P>

<P>
<DEL>If the operand has a class type, the operand is converted to a
pointer type by calling the above-mentioned conversion function, and
the converted operand is used in place of the original operand for the
remainder of this subclause.</DEL> ... </P>

</BLOCKQUOTE>
</LI>

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

<BLOCKQUOTE>

The <DEL><I>cast-expression</I> in</DEL> <INS>operand of</INS>
a <I>delete-expression</I> shall be evaluated exactly once.

</BLOCKQUOTE>
</LI>

</OL>

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

<OL>
<LI>
<P>Change in 7.6.2.9 [<A href="https://wg21.link/expr.delete#1">expr.delete</A>] paragraph 1 and paragraph 2 as
follows:</P>

<BLOCKQUOTE>

<P>... The first alternative is a single-object delete expression, and
the second is an array delete expression. Whenever the delete keyword
is immediately followed by empty square brackets, it shall be
interpreted as the second alternative. [ Footnote: ... ] If the
operand is of class type, it is contextually implicitly converted
(7.3 [<A href="https://wg21.link/conv">conv</A>]) to a pointer to object type <INS>and the
converted operand is used in place of the original operand for the
remainder of this subclause</INS>. <DEL>[ Footnote: ...]</DEL>  Otherwise, it
shall be a prvalue of pointer to object
type. The <I>delete-expression</I> has type void.
</P>

<P>
<DEL>If the operand has a class type, the operand is converted to a
pointer type by calling the above-mentioned conversion function, and
the converted operand is used in place of the original operand for the
remainder of this subclause.</DEL> ...</P>

</BLOCKQUOTE>
</LI>

<LI>
<P>Delete 7.6.2.9 [<A href="https://wg21.link/expr.delete#4">expr.delete</A>] paragraph 4:</P>

<BLOCKQUOTE>

<DEL>The <I>cast-expression</I> in a <I>delete-expression</I> shall be
evaluated exactly once.</DEL>

</BLOCKQUOTE>
</LI>

</OL>

<BR><BR><HR>
<A NAME="2818"></A><H4>2818.
  
Use of predefined reserved identifiers
</H4>
<B>Section: </B>5.10&#160; [<A href="https://wg21.link/lex.name">lex.name</A>]
 &#160;&#160;&#160;

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

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

 <B>Date: </B>2023-01-18


<P>Subclause 5.10 [<A href="https://wg21.link/lex.name#3">lex.name</A>] paragraph 3 specifies:</P>

<BLOCKQUOTE>

In addition, some identifiers appearing as a <I>token</I> or
<I>preprocessing-token</I> are reserved for use by C++ implementations
and shall not be used otherwise; no diagnostic is required.
<UL>
<LI>
Each identifier that contains a double underscore <TT>__</TT>
or begins with an underscore followed by an uppercase letter is
reserved to the implementation for any use. </LI>
<LI>Each identifier
that begins with an underscore is reserved to the implementation for
use as a name in the global namespace.</LI>
</UL>

</BLOCKQUOTE>

<P>That implies that uses of standard-specified predefined macros
(15.11 [<A href="https://wg21.link/cpp.predefined">cpp.predefined</A>]) or feature-test macros
(17.3.2 [<A href="https://wg21.link/version.syn">version.syn</A>]) make the program ill-formed. This does
not appear to be the intent.</P>

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

<P>Change in 5.10 [<A href="https://wg21.link/lex.name#3">lex.name</A>] paragraph 3 and add bullets as follows:</P>

<BLOCKQUOTE>

In addition, some identifiers appearing as a <I>token</I> or
<I>preprocessing-token</I> are reserved for use by C++ implementations
and shall not be used otherwise; no diagnostic is required.
<UL>
<LI>Each identifier that contains a double underscore <TT>__</TT> or
begins with an underscore followed by an uppercase letter is reserved
to the implementation for any use<INS>, except for</INS>
<UL class="ins">
<LI>the macros specified in 15.11 [<A href="https://wg21.link/cpp.predefined">cpp.predefined</A>],</LI>
<LI>the function-local predefined variable
(9.5.1 [<A href="https://wg21.link/dcl.fct.def.general">dcl.fct.def.general</A>]), and</LI>
<LI>the macros and identifiers declared in the standard library as
specified in Clause 17 [<A href="https://wg21.link/support">support</A>] through Clause 33 [<A href="https://wg21.link/thread">thread</A>],
and Clause Annex D [<A href="https://wg21.link/depr">depr</A>].  [ Note: This affects macros in
17.3.2 [<A href="https://wg21.link/version.syn">version.syn</A>], 31.13.1 [<A href="https://wg21.link/cstdio.syn">cstdio.syn</A>], and
D.11 [<A href="https://wg21.link/depr.c.macros">depr.c.macros</A>] as well as identifiers in
17.2.2 [<A href="https://wg21.link/cstdlib.syn">cstdlib.syn</A>]. -- end note ]
</LI>
</UL>
</LI>
<LI>Each identifier that begins with an underscore is reserved to the
implementation for use as a name in the global namespace.</LI>
</UL>

</BLOCKQUOTE>

<P><B>CWG 2024-03-20</B></P>

<P>The exceptions should not be specified using a specific list,
which might become stale in the future.</P>

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

<P>Change in 5.10 [<A href="https://wg21.link/lex.name#3">lex.name</A>] paragraph 3 and add bullets as follows:</P>

<BLOCKQUOTE>

In addition, some identifiers appearing as a <I>token</I> or
<I>preprocessing-token</I> are reserved for use by C++ implementations
and shall not be used otherwise; no diagnostic is required.
<UL>
<LI>Each identifier that contains a double underscore <TT>__</TT> or
begins with an underscore followed by an uppercase letter<INS>, other
than those specified in this document (for
example, <TT>__cplusplus</TT> (15.11 [<A href="https://wg21.link/cpp.predefined">cpp.predefined</A>])), </INS> is
reserved to the implementation for any use.
</LI>
<LI>Each identifier that begins with an underscore is reserved to the
implementation for use as a name in the global namespace.</LI>
</UL>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2819"></A><H4>2819.
  
Cast from null pointer value in a constant expression
</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>Jason Merrill
 &#160;&#160;&#160;

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




<P>Subclause 7.7 [<A href="https://wg21.link/expr.const#5.14">expr.const</A>] bullet 5.14 was amended by
P2738R1 to support certain casts from <TT>void*</TT> to object pointer
types.  The bullet specifies:</P>

<BLOCKQUOTE>

<UL>
<LI>...</LI>
<LI>a conversion from a prvalue P of type &#8220;pointer to cv void&#8221;
to a pointer-to-object type T unless P points to an object whose type
is similar to T;</LI>
<LI>...</LI>
</UL>

</BLOCKQUOTE>

<P>This wording does not, but should, support null pointer values. The
implementation burden is negligible.</P>

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

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

<BLOCKQUOTE>

<UL>
<LI>...</LI>
<LI>a conversion from a prvalue P of type &#8220;pointer to cv
void&#8221; to a pointer-to-object type T unless P <INS>is a null
pointer value or</INS> points to an object whose type is similar to
T;</LI>
<LI>...</LI>
</UL>

</BLOCKQUOTE>

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

<P>CWG seeks approval from EWG for the design direction.
See <A HREF="https://github.com/cplusplus/papers/issues/1698">paper issue 1698</A>.
</P>

<P><B>EWG 2024-03-18</B></P>

<P>EWG approves.</P>

<P><B>CWG 2024-04-19</B></P>

<P>This issue is not a DR.</P>

<BR><BR><HR>
<A NAME="2836"></A><H4>2836.
  
Conversion rank of <TT>long double</TT> and extended floating-point types
</H4>
<B>Section: </B>6.8.6&#160; [<A href="https://wg21.link/conv.rank">conv.rank</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Joshua Cranmer
 &#160;&#160;&#160;

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


<P>Consider:</P>

<PRE>
  auto f(long double x, std::float64_t y) {
    return x + y;
  }
</PRE>

<P>What is the return type of <TT>f</TT>?</P>

<P>Suppose an implementation uses the same size and semantics for all
of <TT>double</TT>, <TT>long double</TT>, and <TT>std::float64_t</TT>.
C23 prefers the IEEE interchange type (i.e. <TT>std::float64_t</TT>)
over <TT>long double</TT> and <TT>double</TT>.  In contrast, C++
chooses <TT>long double</TT>, which has a higher rank than
<TT>double</TT>, but <TT>std::float64_t</TT> is specified to have the
same rank as <TT>double</TT>.
</P>

<P>This outcome conflicts with the documented goal of P1467 that C++
and C conversion rules be aligned.</P>

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

<P>Change in 6.8.6 [<A href="https://wg21.link/conv.rank#2.5">conv.rank</A>] bullet 2.5 as follows:</P>

<BLOCKQUOTE>

<UL>
<LI>...</LI>
<LI>An extended floating-point type with the same set of values as
more than one cv-unqualified standard floating-point type has a rank
equal to the <INS>highest</INS> rank <DEL>of double</DEL> <INS>among
such types</INS>.</LI>
</UL>

</BLOCKQUOTE>

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

<P>The suggested resolution would make a conversion from
<TT>std::float64_t</TT> to <TT>double</TT> not implicit, which is not
desirable.</P>

<P>David Olsen, one of the authors of P1467, asserts that the
deviation from C is intentional, and was discussed with the C
floating-point study group.</P>

<P>Forwarding to EWG via
<A HREF="https://github.com/cplusplus/papers/issues/1699">paper issue 1699</A>
to confirm that the deviation from C is intentional and thus an Annex C
entry should be created.
</P>

<P><B>EWG 2024-03-18</B></P>

<P>This issue should be closed as NAD.</P>

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

<P>Add a new paragraph in C.7.3 [<A href="https://wg21.link/diff.basic">diff.basic</A>] as follows:</P>

<BLOCKQUOTE class="ins">
<B>Affected subclause:</B> 6.8.6 [<A href="https://wg21.link/conv.rank">conv.rank</A>]<BR>
<B>Change:</B> Conversion rank of same-sized <TT>long double</TT> vs. <TT>std::float64_t</TT><BR>
<B>Rationale:</B> Provide implicit conversion from <TT>std::float64_t</TT> to <TT>double</TT>.<BR>
<B>Effect on original feature:</B> Change of semantically well-defined feature.<BR>
<B>Difficulty of converting:</B> Trivial: explicitly convert to the desired type.<BR>
<B>How widely used:</B> Rarely.
</BLOCKQUOTE>

<P><B>CWG 2024-04-19</B></P>

<P>The name <TT>std::float64_t</TT> is not valid C.  CWG resolved to
adding a note to 6.8.6 [<A href="https://wg21.link/conv.rank#2.5">conv.rank</A>] bullet 2.5 instead.</P>

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

<P>Change in 6.8.6 [<A href="https://wg21.link/conv.rank#2.5">conv.rank</A>] bullet 2.5 as follows:</P>

<BLOCKQUOTE>

<UL>
<LI>...</LI>
<LI>An extended floating-point type with the same set of values as
more than one cv-unqualified standard floating-point type has a rank
equal to the rank of double.  <INS>[ Note: The treatment
of <TT>std::float64_t</TT> differs from that of the
analoguous <TT>_Float64</TT> in C, for example on platforms where all
of <TT>long double</TT>, <TT>double</TT>, and <TT>std::float64_t</TT>
have the same set of values (see ISO/IEC 9899:2024 H.4.2). -- end note
]</INS>
</LI>
</UL>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2858"></A><H4>2858.
  
Declarative <I>nested-name-specifier</I>s and <I>pack-index-specifier</I>s
</H4>
<B>Section: </B>7.5.4.3&#160; [<A href="https://wg21.link/expr.prim.id.qual">expr.prim.id.qual</A>]
 &#160;&#160;&#160;

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

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

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


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

<P>Subclause 7.5.4.3 [<A href="https://wg21.link/expr.prim.id.qual#2">expr.prim.id.qual</A>] paragraph 2 specifies:</P>

<BLOCKQUOTE>

... A declarative <I>nested-name-specifier</I> shall not have
a <I>decltype-specifier</I>. ...

</BLOCKQUOTE>

<P>This should have been adjusted by P2662R3 (Pack Indexing) to
read <I>computed-type-specifier</I>.</P>

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

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

<BLOCKQUOTE>

... A declarative <I>nested-name-specifier</I> shall not have
a <DEL><I>decltype-specifier</I></DEL>
<INS><I>computed-type-specifier</I></INS>. ...

</BLOCKQUOTE>

<P><B>CWG 2024-06-26</B></P>

<P>This is not a DR.</P>

<BR><BR><HR>
<A NAME="2859"></A><H4>2859.
  
Value-initialization with multiple 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>Brian Bi
 &#160;&#160;&#160;

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


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

<P>Subclause 9.4.1 [<A href="https://wg21.link/dcl.init.general#9">dcl.init.general</A>] paragraph 9 specifies (as
modified by issue 2820):</P>

<BLOCKQUOTE>

To <I>value-initialize</I> an object of type T means:
<UL>
<LI>If T is a (possibly
cv-qualified) class type (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 then
default-initialized.</LI>
</UL>
</LI>
<LI>...</LI>
</UL>

</BLOCKQUOTE>

<P>Per the specification, no zero-initialization occurs if the class
has <I>any</I> user-provided default constructor, even if that
constructor is not actually selected for the default initialization.
This is observable in a constant expression, where reads of
uninitialized data members are ill-formed.</P>

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

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

<BLOCKQUOTE>

The lifetime of an object or reference is a runtime property of the
object or reference. A variable is said to have <I>vacuous
initialization</I> if it is default-initialized<INS>, no other
initialization is performed,</INS> and, if it is of class type or a
(possibly multidimensional) array thereof, <INS>a trivial constructor
of</INS> that class type <DEL>has a trivial default
constructor</DEL> <INS>is selected for the
default-initialization</INS>. The lifetime of an object of type T
begins when: ...

</BLOCKQUOTE>

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

<BLOCKQUOTE>

To <I>value-initialize</I> an object of type T means:
<UL>
<LI>If T is a (possibly cv-qualified) class type
(Clause 11 [<A href="https://wg21.link/class">class</A>]), then
<UL class="del">
<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 then
default-initialized.</LI>
</UL>
<INS>let <TT>C</TT> be the constructor selected to default-initialize
the object, if any. If <TT>C</TT> is not user-provided, the object is first
zero-initialized.  In all cases, the object is then
default-initialized.</INS>
</LI>
<LI>...</LI>
</UL>

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

<BR><BR><HR>
<A NAME="2861"></A><H4>2861.
  
<TT>dynamic_cast</TT> on bad pointer value
</H4>
<B>Section: </B>7.6.1.7&#160; [<A href="https://wg21.link/expr.dynamic.cast">expr.dynamic.cast</A>]
 &#160;&#160;&#160;

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

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

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


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

<P>Base-to-derived casts and cross-casts need to inspect the vtable of
a polymorphic type.  However, this is not defined as an "access" and
there is no provision for undefined behavior analoguous to
7.2.1 [<A href="https://wg21.link/basic.lval#11">basic.lval</A>] paragraph 11.</P>

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

<OL>
<LI>
<P>Add a new paragraph after 7.6.1.7 [<A href="https://wg21.link/expr.dynamic.cast#6">expr.dynamic.cast</A>] paragraph 6 as
follows:</P>

<BLOCKQUOTE>

<P>If v is a null pointer value, the result is a null pointer value.</P>

<P class="ins">
If <TT>v</TT> has type "pointer to <I>cv</I> <TT>U</TT>"
and <TT>v</TT> does not point to an object whose type is similar
(7.3.6 [<A href="https://wg21.link/conv.qual">conv.qual</A>]) to <TT>U</TT> and that is within its
lifetime or within its period of construction or destruction
(11.9.5 [<A href="https://wg21.link/class.cdtor">class.cdtor</A>]), the behavior is undefined.
If <TT>v</TT> is a glvalue of type <TT>U</TT> and <TT>v</TT> does not
refer to an object whose type is similar to <TT>U</TT> and that is
within its lifetime or within its period of construction or
destruction, the behavior is undefined.
</P>

</BLOCKQUOTE>
</LI>

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

<BLOCKQUOTE>

A prvalue <INS><TT>v</TT></INS> of type &#8220;pointer to cv D&#8221;,
where D is a complete class type, can be converted to a prvalue of
type &#8220;pointer to cv B&#8221;, where B is a base class
(11.7 [<A href="https://wg21.link/class.derived">class.derived</A>]) of D. If B is an inaccessible
(11.8 [<A href="https://wg21.link/class.access">class.access</A>]) or ambiguous (6.5.2 [<A href="https://wg21.link/class.member.lookup">class.member.lookup</A>])
base class of D, a program that necessitates this conversion is
ill-formed. <DEL>The result of the conversion is a pointer to the base
class subobject of the derived class object. The null pointer value is
converted to the null pointer value of the destination type.</DEL>
<INS>If <TT>v</TT> is a null pointer value, the result is a null
pointer value.  Otherwise, if <TT>B</TT> is a virtual base class
of <TT>D</TT> and <TT>v</TT> does not point to an object whose type is
similar (7.3.6 [<A href="https://wg21.link/conv.qual">conv.qual</A>]) to <TT>D</TT> and that is within
its lifetime or within its period of construction or destruction
(11.9.5 [<A href="https://wg21.link/class.cdtor">class.cdtor</A>]), the behavior is undefined. Otherwise,
the result is a pointer to the base class subobject of the derived
class object.</INS>

</BLOCKQUOTE>
</LI>
</OL>
<BR><BR><HR>
<A NAME="2864"></A><H4>2864.
  
Narrowing floating-point conversions
</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>Brian Bi
 &#160;&#160;&#160;

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




<P>Consider:</P>

<PRE>
  float f = {1e100};
</PRE>

<P>This is rejected as narrowing on all implementations.
Issue 2723 made the example non-narrowing,
which seems incorrect on an IEEE platform.</P>

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

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

<BLOCKQUOTE>

A <I>narrowing conversion</I> is an implicit conversion
<UL>
<LI>from a floating-point type to an integer type, or</LI>
<LI>from a floating-point type T to another floating-point type whose
floating-point conversion rank is neither greater than nor equal to
that of T, except where the <DEL>source</DEL> <INS>result of the
conversion</INS> is a constant expression and <DEL>the
actual</DEL> <INS>either its</INS> value <DEL>after conversion</DEL>
is <INS>finite and</INS> <DEL>within the range of values that can be
represented (even if it cannot be represented exactly)</DEL> <INS>the
conversion did not overflow, or the values before and after the
conversion are not finite</INS>, or</LI>
<LI>from an integer type ...</LI>
</UL>

</BLOCKQUOTE>

<P><B>Additional notes (April, 2024)</B></P>

<P>According to the proposed wording, since NaNs are not finite,
conversion of NaNs is always non-narrowing.  However, the payload of
the NaN might not be preserved when converting to a smaller
floating-point type.</P>

<BR><BR><HR>
<A NAME="2865"></A><H4>2865.
  
Regression on result of conditional operator
</H4>
<B>Section: </B>7.6.16&#160; [<A href="https://wg21.link/expr.cond">expr.cond</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Christof Meerwald
 &#160;&#160;&#160;

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




<P>Consider:</P>

<PRE>
  #include &lt;concepts&gt;

  template &lt;class T&gt; T get();

  template &lt;class T&gt;
  using X = decltype(true ? get&lt;T const&amp;&gt;() : get&lt;T&gt;());

  struct C { };

  static_assert(std::same_as&lt;X&lt;int&gt;, int&gt;);
  static_assert(std::same_as&lt;X&lt;C&gt;, C const&gt;);  // #1
</PRE>

<P>Before Issue 1895, #1 was well-formed.
With the reformulation based on conversion sequences, #1 is now
ill-formed because both conversion sequences can be formed.</P>

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

<P>Change in 7.6.16 [<A href="https://wg21.link/expr.cond#4.3">expr.cond</A>] bullet 4.3 as follows:</P>

<BLOCKQUOTE>

<UL>
<LI>...</LI>
<LI>If E2 is a prvalue or if neither of the conversion sequences above
can be formed and at least one of the operands has (possibly
cv-qualified) class type:
<UL>
<LI>if T1 and T2 are the same class type (ignoring
cv-qualification)<INS>:</INS>
<UL>
<LI>
<DEL>and</DEL> <INS>if</INS> T2 is at least as cv-qualified as
T1, the target type is T2,</LI>
<LI class="ins">otherwise, no conversion sequence is formed for this operand;</LI>
</UL>
</LI>
<LI>otherwise, if T2 is a base class of T1, the target type is cv1 T2,
where cv1 denotes the cv-qualifiers of T1<DEL>,</DEL> <INS>;</INS>
</LI>
<LI>otherwise, the target type is the type that E2 would have after
applying the lvalue-to-rvalue (7.3.2 [<A href="https://wg21.link/conv.lval">conv.lval</A>]),
array-to-pointer (7.3.3 [<A href="https://wg21.link/conv.array">conv.array</A>]), and function-to-pointer
(7.3.4 [<A href="https://wg21.link/conv.func">conv.func</A>]) standard conversions.</LI>
</UL>
</LI>
</UL>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2867"></A><H4>2867.
  
Order of initialization for structured bindings
</H4>
<B>Section: </B>9.6&#160; [<A href="https://wg21.link/dcl.struct.bind">dcl.struct.bind</A>]
 &#160;&#160;&#160;

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

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

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




<P>Consider:</P>

<PRE>
  auto [a, b] = f(X{});
</PRE>

<P>If <TT>X</TT> is a tuple-like type, this is transformed to
approximately the following:</P>

<PRE>
  auto e = f(X{});
  T1 &amp;a = get&lt;0&gt;(std::move(e));
  T2 &amp;b = get&lt;1&gt;(std::move(e));
</PRE>

<P>However, the sequencing of the initializations of e, a, and b is
not specified.  Further, the temporary <TT>X{}</TT> should be
destroyed after the initializations of a and b.</P>

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

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

<BLOCKQUOTE>

A <I>full-expression</I> is
<UL>
<LI>an unevaluated operand (7.2.3 [<A href="https://wg21.link/expr.context">expr.context</A>]),</LI>

<LI>a <I>constant-expression</I> (7.7 [<A href="https://wg21.link/expr.const">expr.const</A>]),</LI>

<LI>an immediate invocation (7.7 [<A href="https://wg21.link/expr.const">expr.const</A>]),</LI>

<LI>an <I>init-declarator</I> (9.3 [<A href="https://wg21.link/dcl.decl">dcl.decl</A>]) or
a <I>mem-initializer</I> (11.9.3 [<A href="https://wg21.link/class.base.init">class.base.init</A>]), including the
constituent expressions of the initializer,</LI>

<LI class="ins">the <I>initializer</I>s for all uniquely-named
variables introduced by a structured binding declaration
(9.6 [<A href="https://wg21.link/dcl.struct.bind">dcl.struct.bind</A>]), including the constituent expressions of
all initializers,</LI>

<LI>an invocation of a destructor generated at
the end of the lifetime of an object other than a temporary object
(6.7.7 [<A href="https://wg21.link/class.temporary">class.temporary</A>]) whose lifetime has not been extended, or</LI>

<LI>an expression that is not a subexpression of another expression
and that is not otherwise part of a full-expression.</LI>
</UL>
...
</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 9.6 [<A href="https://wg21.link/dcl.struct.bind#4">dcl.struct.bind</A>] paragraph 4 as follows:</P>

<BLOCKQUOTE>

... Each v<sub>i</sub> is the name of an lvalue of type T<sub>i</sub>
that refers to the object bound to r<sub>i</sub>; the referenced type
is T<sub>i</sub>.

<INS>The initialization of e is sequenced before the initialization of
any r<sub>i</sub>.  The initialization of r<sub>i</sub> is sequenced
before the initialization of r<sub>j</sub> if i &lt; j.</INS>

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

<P><B>CWG 2024-05-03</B></P>

<P>CWG tentatively agreed that all temporaries in a structured binding
(including those from default arguments of <TT>get</TT> invocations)
should persist until the semicolon on the declaration as written.</P>

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

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

<BLOCKQUOTE>

A <I>full-expression</I> is
<UL>
<LI>an unevaluated operand (7.2.3 [<A href="https://wg21.link/expr.context">expr.context</A>]),</LI>

<LI>a <I>constant-expression</I> (7.7 [<A href="https://wg21.link/expr.const">expr.const</A>]),</LI>

<LI>an immediate invocation (7.7 [<A href="https://wg21.link/expr.const">expr.const</A>]),</LI>

<LI>an <I>init-declarator</I> (9.3 [<A href="https://wg21.link/dcl.decl">dcl.decl</A>])
<INS>, an <I>initializer</I> of a structured
binding declaration (9.1 [<A href="https://wg21.link/dcl.pre">dcl.pre</A>]),</INS> or
a <I>mem-initializer</I> (11.9.3 [<A href="https://wg21.link/class.base.init">class.base.init</A>]), including the
constituent expressions of the initializer,</LI>

<LI>an invocation of a destructor generated at
the end of the lifetime of an object other than a temporary object
(6.7.7 [<A href="https://wg21.link/class.temporary">class.temporary</A>]) whose lifetime has not been extended, or</LI>

<LI>an expression that is not a subexpression of another expression
and that is not otherwise part of a full-expression.</LI>
</UL>
...
</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 9.6 [<A href="https://wg21.link/dcl.struct.bind#4">dcl.struct.bind</A>] paragraph 4 as follows:</P>

<BLOCKQUOTE>

... Each v<sub>i</sub> is the name of an lvalue of type T<sub>i</sub>
that refers to the object bound to r<sub>i</sub>; the referenced type
is T<sub>i</sub>.

<INS>The initialization of e is sequenced before the initialization of
any r<sub>i</sub>.  The initialization of each r<sub>i</sub> is sequenced
before the initialization of any r<sub>j</sub> where i &lt; j.</INS>

</BLOCKQUOTE>
</LI>

<LI>
<P>Append a new paragraph at the end of 9.6 [<A href="https://wg21.link/dcl.struct.bind">dcl.struct.bind</A>] as follows:</P>

<BLOCKQUOTE>

<P>... [ Example: ...
The type of the id-expression x is "int", the type of the id-expression y is "const volatile double". -- end example ]</P>

<P class="ins">
The initialization of <I>e</I> and of any r<sub>i</sub> are sequenced
before the destruction of any temporary object introduced by
the <I>initializer</I> for <I>e</I> or by the <I>initializer</I>s for
the r<sub>i</sub>.  The temporary objects are destroyed in the
reverse order of their construction.
</P>

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

<P><B>CWG 2024-06-14</B></P>

<P>The specification for the lifetime of temporaries should be moved
to 6.7.7 [<A href="https://wg21.link/class.temporary">class.temporary</A>].)</P>

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

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

<BLOCKQUOTE>

There are <DEL>four</DEL> <INS>five</INS> contexts in which
temporaries are destroyed at a different point than the end of the
full-expression. ...

</BLOCKQUOTE>

</LI>

<LI>
<P>Insert a new paragraph after 6.7.7 [<A href="https://wg21.link/class.temporary#7">class.temporary</A>] paragraph 7 as follows:</P>



<BLOCKQUOTE>

<P>The fourth context is when a temporary object 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>.</P>

<P class="ins">
The fifth context is when a temporary object is created in a
structured binding declaration (9.6 [<A href="https://wg21.link/dcl.struct.bind">dcl.struct.bind</A>]).  Any
temporary objects introduced by the <I>initializer</I>s for the
variables with unique names are destroyed at the end of
the structured binding declaration.
</P>

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 6.9.1 [<A href="https://wg21.link/intro.execution#5">intro.execution</A>] paragraph 5 as follows:</P>

<BLOCKQUOTE>

A <I>full-expression</I> is
<UL>
<LI>an unevaluated operand (7.2.3 [<A href="https://wg21.link/expr.context">expr.context</A>]),</LI>

<LI>a <I>constant-expression</I> (7.7 [<A href="https://wg21.link/expr.const">expr.const</A>]),</LI>

<LI>an immediate invocation (7.7 [<A href="https://wg21.link/expr.const">expr.const</A>]),</LI>

<LI>an <I>init-declarator</I> (9.3 [<A href="https://wg21.link/dcl.decl">dcl.decl</A>])
<INS>(including such introduced by a structured binding (9.6 [<A href="https://wg21.link/dcl.struct.bind">dcl.struct.bind</A>]))</INS> or
a <I>mem-initializer</I> (11.9.3 [<A href="https://wg21.link/class.base.init">class.base.init</A>]), including the
constituent expressions of the initializer,</LI>

<LI>an invocation of a destructor generated at
the end of the lifetime of an object other than a temporary object
(6.7.7 [<A href="https://wg21.link/class.temporary">class.temporary</A>]) whose lifetime has not been extended, or</LI>

<LI>an expression that is not a subexpression of another expression
and that is not otherwise part of a full-expression.</LI>
</UL>
...
</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 9.6 [<A href="https://wg21.link/dcl.struct.bind#4">dcl.struct.bind</A>] paragraph 4 as follows:</P>

<BLOCKQUOTE>

... Each v<sub>i</sub> is the name of an lvalue of type T<sub>i</sub>
that refers to the object bound to r<sub>i</sub>; the referenced type
is T<sub>i</sub>.

<INS>The initialization of e is sequenced before the initialization of
any r<sub>i</sub>.  The initialization of each r<sub>i</sub> is sequenced
before the initialization of any r<sub>j</sub> where i &lt; j.</INS>

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

<BR><BR><HR>
<A NAME="2869"></A><H4>2869.
  
<TT>this</TT> in local classes
</H4>
<B>Section: </B>7.5.2&#160; [<A href="https://wg21.link/expr.prim.this">expr.prim.this</A>]
 &#160;&#160;&#160;

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

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

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


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

<P>Consider:</P>

<PRE>
  struct A {
    static void f() {
      struct B {
        void *g() { return this; }
       };
     }
  };
</PRE>

<P>According to 7.5.2 [<A href="https://wg21.link/expr.prim.this#3">expr.prim.this</A>] paragraph 3, this example is
ill-formed, because <TT>this</TT> "appears within" the declaration of
a static member function.  The qualification "of the current class"
can be read as attaching to explicit object member functions only.</P>

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

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

<BLOCKQUOTE>

If a declaration declares a member function or member function
template of a class X, the expression <TT>this</TT> is a prvalue of type
&#8220;pointer to <I>cv-qualifier-seq</I> X&#8221; wherever X is the
current class between the optional <I>cv-qualifier-seq</I> and the end
of the <I>function-definition</I>, <I>member-declarator</I> , or
<I>declarator</I>. <DEL>It shall not appear within
the</DEL> <INS>The</INS> declaration <DEL>of either</DEL> <INS>that
determines the type of <TT>this</TT> shall declare neither</INS> a
static member function <DEL>or</DEL> <INS>nor</INS> an explicit object
member function of the current class (although its type and value
category are defined within such member functions as they are within
an implicit object member function).

</BLOCKQUOTE>

<P><B>CWG 2024-05-03</B></P>

<P>CWG preferred a smaller surgery to avoid the English parsing issue.</P>

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

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

<BLOCKQUOTE>

If a declaration declares a member function or member function
template of a class X, the expression <TT>this</TT> is a prvalue of type
&#8220;pointer to <I>cv-qualifier-seq</I> X&#8221; wherever X is the
current class between the optional <I>cv-qualifier-seq</I> and the end
of the <I>function-definition</I>, <I>member-declarator</I>, or
<I>declarator</I>. It shall not appear within
the declaration of <DEL>either</DEL> a
static <DEL>member function</DEL> or <DEL>an</DEL> explicit object
member function of the current class (although its type and value
category are defined within such member functions as they are within
an implicit object member function).

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2870"></A><H4>2870.
  
Combining absent <I>encoding-prefix</I>es
</H4>
<B>Section: </B>5.13.5&#160; [<A href="https://wg21.link/lex.string">lex.string</A>]
 &#160;&#160;&#160;

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

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

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


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

<P>Subclause 5.13.5 [<A href="https://wg21.link/lex.string#7">lex.string</A>] paragraph 7 does not properly
handle the case where both <I>encoding-prefix</I>es are absent:</P>

<BLOCKQUOTE>

The common <I>encoding-prefix</I> for a sequence of
adjacent <I>string-literal</I>s is determined pairwise as follows: If
two <I>string-literal</I>s have the same <I>encoding-prefix</I> , the
common <I>encoding-prefix</I> is that <I>encoding-prefix</I> . If
one <I>string-literal</I> has no <I>encoding-prefix</I> , the
common <I>encoding-prefix</I> is that of the
other <I>string-literal</I>. Any other combinations are ill-formed.

</BLOCKQUOTE>

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

<P>Change in 5.13.5 [<A href="https://wg21.link/lex.string#7">lex.string</A>] paragraph 7 as follows:</P>

<BLOCKQUOTE>

The common <I>encoding-prefix</I> for a sequence of
adjacent <I>string-literal</I>s is determined pairwise as
follows: <DEL>If two <I>string-literal</I>s have the same
<I>encoding-prefix</I>, the common <I>encoding-prefix</I> is that
<I>encoding-prefix</I>.</DEL> If one <I>string-literal</I> has no
<I>encoding-prefix</I>, the common <I>encoding-prefix</I> is that of
the other <I>string-literal</I> <INS>or is absent if the other
<I>string-literal</I> has no <I>encoding-prefix</I>. Otherwise,
both <I>string-literal</I>s shall have the same
<I>encoding-prefix</I>, and the common <I>encoding-prefix</I> is that
<I>encoding-prefix</I></INS>. <DEL>Any other combinations are
ill-formed.</DEL>

</BLOCKQUOTE>

<P><B>CWG 2024-05-03</B></P>

<P>CWG preferred a holistic instead of a pairwise approach.</P>

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

<P>Change in 5.13.5 [<A href="https://wg21.link/lex.string#7">lex.string</A>] paragraph 7 as follows:</P>

<BLOCKQUOTE>

<P class="del">The common <I>encoding-prefix</I> for a sequence of
adjacent <I>string-literal</I>s is determined pairwise as follows: If
two <I>string-literal</I>s have the same <I>encoding-prefix</I> , the
common <I>encoding-prefix</I> is that <I>encoding-prefix</I> . If
one <I>string-literal</I> has no <I>encoding-prefix</I> , the
common <I>encoding-prefix</I> is that of the
other <I>string-literal</I>. Any other combinations are ill-formed.</P>

<P class="ins">
The <I>string-literal</I>s in any sequence of
adjacent <I>string-literal</I>s shall have at most one
unique <I>encoding-prefix</I> among them.  The common
<I>encoding-prefix</I> of the sequence is that <I>encoding-prefix</I>,
if any.</P>

</BLOCKQUOTE>
<BR><BR><HR>
<A NAME="2871"></A><H4>2871.
  
User-declared constructor templates inhibiting default constructors
</H4>
<B>Section: </B>11.4.5.2&#160; [<A href="https://wg21.link/class.default.ctor">class.default.ctor</A>]
 &#160;&#160;&#160;

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

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

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


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

<P>Subclause 11.4.5.2 [<A href="https://wg21.link/class.default.ctor#1">class.default.ctor</A>] paragraph 1 does not, but
should, consider user-declared constructor templates.</P>

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

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

<BLOCKQUOTE>

... If there is no user-declared constructor <INS>or constructor
template</INS> for class X, a non-explicit constructor having no
parameters is implicitly declared as defaulted
(9.5 [<A href="https://wg21.link/dcl.fct.def">dcl.fct.def</A>]). ...

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2872"></A><H4>2872.
  
Linkage and unclear "can be referred to"
</H4>
<B>Section: </B>6.6&#160; [<A href="https://wg21.link/basic.link">basic.link</A>]
 &#160;&#160;&#160;

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

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

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




<P>It is unclear what "can be referred to" means in
6.6 [<A href="https://wg21.link/basic.link#2">basic.link</A>] paragraph 2.  Paragraph 8 provides precise
definitions for "same entity".</P>

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

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

<BLOCKQUOTE class="del">

A name is said to have <I>linkage</I> when it can denote the same object,
reference, function, type, template, namespace or value as a name
introduced by a declaration in another scope:

<UL>
<LI>When a name has external linkage, the entity it denotes can be
referred to by names from scopes of other translation units or from
other scopes of the same translation unit.</LI>
<LI>When a name has module linkage, the entity it denotes can be
referred to by names from other scopes of the same module unit
(10.1 [<A href="https://wg21.link/module.unit">module.unit</A>]) or from scopes of other module units of
that same module.</LI>
<LI>When a
name has internal linkage, the entity it denotes can be referred to by
names from other scopes in the same translation unit.</LI>
<LI>When a name has no linkage, the entity it denotes cannot be
referred to by names from other scopes.</LI>
</UL>

</BLOCKQUOTE>

<BLOCKQUOTE class="ins">

A name can have <I>external linkage</I>, <I>module linkage</I>,
<I>internal linkage</I>, or <I>no linkage</I>, as determined by the
rules below.  [ Note: The linkage of a name determines when
corresponding declarations (6.4.1 [<A href="https://wg21.link/basic.scope.scope">basic.scope.scope</A>]) that introduce
that name can declare the same entity. ---end note]

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 11.6 [<A href="https://wg21.link/class.local#3">class.local</A>] paragraph 3 as follows:</P>

<BLOCKQUOTE>

<DEL>If class X is a local class, a nested class Y may be
declared in class X and later defined in the
definition of class X or be later defined in the same scope as the
definition of class X.</DEL> A class nested within a local class is a local
class.
<INS>A member of a local class X shall be declared only in the
definition of X or the nearest enclosing block scope of X.</INS>

</BLOCKQUOTE>

</LI>
</OL>

<P><B>CWG 2024-05-03</B></P>

<P>CWG opined to split off the second change (see
issue 2890) and clarify the note.</P>

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

<P>Replace in 6.6 [<A href="https://wg21.link/basic.link#2">basic.link</A>] paragraph 2 as follows:</P>

<BLOCKQUOTE class="del">

A name is said to have <I>linkage</I> when it can denote the same object,
reference, function, type, template, namespace or value as a name
introduced by a declaration in another scope:

<UL>
<LI>When a name has external linkage, the entity it denotes can be
referred to by names from scopes of other translation units or from
other scopes of the same translation unit.</LI>
<LI>When a name has module linkage, the entity it denotes can be
referred to by names from other scopes of the same module unit
(10.1 [<A href="https://wg21.link/module.unit">module.unit</A>]) or from scopes of other module units of
that same module.</LI>
<LI>When a
name has internal linkage, the entity it denotes can be referred to by
names from other scopes in the same translation unit.</LI>
<LI>When a name has no linkage, the entity it denotes cannot be
referred to by names from other scopes.</LI>
</UL>

</BLOCKQUOTE>

<BLOCKQUOTE class="ins">

A name can have <I>external linkage</I>, <I>module linkage</I>,
<I>internal linkage</I>, or <I>no linkage</I>, as determined by the
rules below.  [ Note: All declarations of an entity with a name with
internal linkage appear in the same translation unit.  All
declarations of an entity with module linkage are attached to the same
module. ---end note]

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2874"></A><H4>2874.
  
Qualified declarations of partial specializations
</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>Krystian Stasiowski
 &#160;&#160;&#160;

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


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

<P>Consider:</P>

<PRE>
  namespace N {
    template&lt;typename T&gt;
    struct A;
  }

  template&lt;&gt;
  struct N::A&lt;int&gt;;     //<SPAN CLASS="cmnt"> OK</SPAN>

  template&lt;typename T&gt;
  struct N::A&lt;T*&gt;;      //<SPAN CLASS="cmnt"> error: invalid use of elaborated-type-specifier with a qualified-id</SPAN>
</PRE>

<P>However, all major implementations support this.</P>

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

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

<BLOCKQUOTE>

If an <I>elaborated-type-specifier</I> is the sole constituent of a
declaration, the declaration is ill-formed unless it is an explicit
specialization (13.9.4 [<A href="https://wg21.link/temp.expl.spec">temp.expl.spec</A>]),
<INS>a partial specialization (13.7.6 [<A href="https://wg21.link/temp.spec.partial">temp.spec.partial</A>]),</INS> an
explicit instantiation (13.9.3 [<A href="https://wg21.link/temp.explicit">temp.explicit</A>])<INS>,</INS> or it
has one of the following forms:
<PRE>
  <I>class-key</I> <I>attribute-specifier-seqopt</I> <I>identifier</I> ;
  <I>class-key</I> <I>attribute-specifier-seqopt</I> <I>simple-template-id</I> ;
</PRE>
In the first case, the <I>elaborated-type-specifier</I> declares the
identifier as a <I>class-name</I>. The second case shall appear only
in an <I>explicit-specialization</I> (13.9.4 [<A href="https://wg21.link/temp.expl.spec">temp.expl.spec</A>]) or
in a <I>template-declaration</I> (where it declares a partial
specialization <DEL>(13.7 [<A href="https://wg21.link/temp.decls">temp.decls</A>])</DEL>.
The <I>attribute-specifier-seq</I>, if any, appertains to the class or
template being declared.

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2876"></A><H4>2876.
  
Disambiguation of <TT>T x = delete("text")</TT>
</H4>
<B>Section: </B>9.5.1&#160; [<A href="https://wg21.link/dcl.fct.def.general">dcl.fct.def.general</A>]
 &#160;&#160;&#160;

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

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

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




<P>P2573R2 (= delete("should have a reason");), adopted in Tokyo,
does not disambiguate the following syntax:</P>

<PRE>
  using T = void ();
  using U = int;

  T a = delete ("hello");
  U b = delete ("hello");
</PRE>

<P>Either may be parsed as a (semantically
ill-formed) <I>simple-declaration</I> whose initializer is
a <I>delete-expression</I> or as a <I>function-definition</I>.</P>

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

<P>Change and split 9.1 [<A href="https://wg21.link/dcl.pre#9">dcl.pre</A>] paragraph 9 as follows:</P>

<BLOCKQUOTE>
<P class="ins">
An object definition causes storage of appropriate size and alignment
to be reserved and any appropriate initialization
(9.4 [<A href="https://wg21.link/dcl.init">dcl.init</A>]) to be done.
</P>

<P>
Syntactic components beyond those found in the general form
of <I>simple-declaration</I> are added to a function declaration to
make a <I>function-definition</I>.
<INS>A token sequence starting with <TT>{</TT> or <TT>=</TT> is
treated as a <I>function-body</I> (9.5.1 [<A href="https://wg21.link/dcl.fct.def.general">dcl.fct.def.general</A>]) 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> (9.4.1 [<A href="https://wg21.link/dcl.init.general">dcl.init.general</A>]).  [
Note: If the 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>].  The function type of a function
definition cannot be specified with a <I>typedef-name</I>
(9.3.4.6 [<A href="https://wg21.link/dcl.fct">dcl.fct</A>]). --end note ]</INS>
<DEL>An object declaration, however, is also a definition unless it
contains the extern specifier and has no initializer
(6.2 [<A href="https://wg21.link/basic.def">basic.def</A>]). An object definition causes storage of
appropriate size and alignment to be reserved and any appropriate
initialization (9.4 [<A href="https://wg21.link/dcl.init">dcl.init</A>]) to be done.</DEL>
</P>

</BLOCKQUOTE>

<P>This drafting also resolves issue 2144.</P>

<BR><BR><HR>
<A NAME="2877"></A><H4>2877.
  
Type-only lookup for <I>using-enum-declarator</I>
</H4>
<B>Section: </B>9.7.2&#160; [<A href="https://wg21.link/enum.udecl">enum.udecl</A>]
 &#160;&#160;&#160;

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

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

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




<P>Issue 2621 claimed to ask the question
whether lookup for <TT>using enum</TT> declarations was supposed to be
type-only, but the example actually highlighted the difference between
<I>elaborated-type-specifier</I> lookup (where finding nothing but
<TT>typedef</TT> names is ill-formed) and ordinary lookup.</P>

<P>However, consider:</P>

<PRE>
  enum A {
    x, y
  };
  void f() {
    int A;
    using enum A;      //<SPAN CLASS="cmnt"> #1, error: names non-type </SPAN>int A
    using T = enum A;  //<SPAN CLASS="cmnt"> #2, OK, names </SPAN>::A
  }
</PRE>

<P>The two situations should both be type-only lookups for
consistency, although #2 would not find <TT>typedef</TT>s.</P>

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

<P>Change in 9.7.2 [<A href="https://wg21.link/enum.udecl#1">enum.udecl</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

A <I>using-enum-declarator</I> names the set of declarations found by
<INS>type-only</INS> lookup (<INS>6.5.1 [<A href="https://wg21.link/basic.lookup.general">basic.lookup.general</A>]</INS>
<DEL>6.5.3 [<A href="https://wg21.link/basic.lookup.unqual">basic.lookup.unqual</A>], 6.5.5 [<A href="https://wg21.link/basic.lookup.qual">basic.lookup.qual</A>]</DEL>) for
the <I>using-enum-declarator</I> <INS>(6.5.3 [<A href="https://wg21.link/basic.lookup.unqual">basic.lookup.unqual</A>],
6.5.5 [<A href="https://wg21.link/basic.lookup.qual">basic.lookup.qual</A>])</INS>. The <I>using-enum-declarator</I>
shall designate a non-dependent type with a
reachable <I>enum-specifier</I>.

</BLOCKQUOTE>

<P><B>Additional notes (May, 2024)</B></P>

<P>An example is desirable.  Also, the treatment of the following
example is unclear:</P>

<PRE>
  template&lt;class T&gt; using AA = T;
  enum AA&lt;E&gt; e; //<SPAN CLASS="cmnt"> ill-formed elaborated-type-specifier</SPAN>
  using enum AA&lt;E&gt;; //<SPAN CLASS="cmnt"> Clang and MSVC reject, GCC and EDG accept</SPAN>
</PRE>

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

<P>Change in 9.7.2 [<A href="https://wg21.link/enum.udecl#1">enum.udecl</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

A <I>using-enum-declarator</I> names the set of declarations found by
<INS>type-only</INS> lookup (<INS>6.5.1 [<A href="https://wg21.link/basic.lookup.general">basic.lookup.general</A>]</INS>
<DEL>6.5.3 [<A href="https://wg21.link/basic.lookup.unqual">basic.lookup.unqual</A>], 6.5.5 [<A href="https://wg21.link/basic.lookup.qual">basic.lookup.qual</A>]</DEL>) for
the <I>using-enum-declarator</I> <INS>(6.5.3 [<A href="https://wg21.link/basic.lookup.unqual">basic.lookup.unqual</A>],
6.5.5 [<A href="https://wg21.link/basic.lookup.qual">basic.lookup.qual</A>])</INS>. The <I>using-enum-declarator</I>
shall designate a non-dependent type with a
reachable <I>enum-specifier</I>. <INS>[ Example:</INS>
<PRE class="ins">
enum E { x };
void f() {
  int E;
  using enum E;   // <SPAN CLASS="cmnt">OK</SPAN>
}
using F = E;
using enum F;     // <SPAN CLASS="cmnt">OK</SPAN>
template&lt;class T&gt; using EE = T;
void g() {
  using enum EE&lt;E&gt;;  // <SPAN CLASS="cmnt">OK</SPAN>
}
</PRE>
<INS>-- end example ]</INS>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2881"></A><H4>2881.
  
Type restrictions for the explicit object parameter of a lambda
</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>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>2024-04-19




<P>Subclause 7.5.5.2 [<A href="https://wg21.link/expr.prim.lambda.closure#5">expr.prim.lambda.closure</A>] paragraph 5 restricts the type
of an explicit object parameter of a lambda to the closure type or
classes derived from the closure type.  It neglects to consider
ambiguous or private derivation scenarios.</P>

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

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

<BLOCKQUOTE>

Given a lambda with a <I>lambda-capture</I>, the type of the explicit
object parameter, if any, of the lambda's function call operator
(possibly instantiated from a function call operator template) shall
be either:
<UL>
<LI>the closure type</LI>
<LI>a class type <INS>publicly and unambiguously</INS> derived from
the closure type, or</LI>
<LI>a reference to a possibly cv-qualified such type.</LI>
</UL>

</BLOCKQUOTE>
</LI>

<LI>
<P>Add a new bullet after 13.10.3.1 [<A href="https://wg21.link/temp.deduct.general#11.10">temp.deduct.general</A>] bullet 11.10:</P>

<BLOCKQUOTE>

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

<LI>Attempting to create a function type in which a parameter has a
type of void, or in which the return type is a function type or array
type.</LI>

<LI class="ins">Attempting to give to an explicit object parameter of
a lambda's function call operator a type not permitted for such
(7.5.5.2 [<A href="https://wg21.link/expr.prim.lambda.closure">expr.prim.lambda.closure</A>]).</LI>
</UL>

</BLOCKQUOTE>

</LI>
</OL>

<P><B>CWG 2024-06-26</B></P>

<P>The following example is not supported by the proposed resolution
and remains ill-formed:</P>

<PRE>
  int main() {
    int x = 0;
    auto lambda = [x] (this auto self) { return x; };
    using Lambda = decltype(lambda);
    struct D : private Lambda {
      D(Lambda l) : Lambda(l) {}
      using Lambda::operator();
      friend Lambda;
    } d(lambda);
    d();
  } 
</PRE>

<BR><BR><HR>
<A NAME="2882"></A><H4>2882.
  
Unclear treatment of conversion to <TT>void</TT>
</H4>
<B>Section: </B>7.6.1.9&#160; [<A href="https://wg21.link/expr.static.cast">expr.static.cast</A>]
 &#160;&#160;&#160;

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

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

 <B>Date: </B>2024-04-24




<P>The ordering of paragraphs in 7.6.1.9 [<A href="https://wg21.link/expr.static.cast">expr.static.cast</A>] appears
to imply that an attempt is made to form an implicit conversion
sequence for conversions to <TT>void</TT>, possibly considering
user-defined conversion functions to <TT>void</TT>.  This is not
intended.</P>

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

<OL>
<LI>
<P>Move 7.6.1.9 [<A href="https://wg21.link/expr.static.cast#6">expr.static.cast</A>] paragraph 6 to before paragraph 4,
strike paragraph 5, and adjust paragraph 7:</P>

<BLOCKQUOTE>

<P class="ins">Any expression can be explicitly converted to type <I>cv</I>
<TT>void</TT>, in which case the operand is a discarded-value expression
(7.2 [<A href="https://wg21.link/expr.prop">expr.prop</A>]).  [<I>Note 3:</I> Such a static_cast has no
result as it is a prvalue of type void; see
7.2.1 [<A href="https://wg21.link/basic.lval">basic.lval</A>]. &#8212;<I>end note</I>]
[<I>Note 4:</I> However, if the value is in a temporary
object (6.7.7 [<A href="https://wg21.link/class.temporary">class.temporary</A>]), the destructor for that object is
not executed until the usual time, and the value of the object is
preserved for the purpose of executing the destructor. &#8212;<I>end
note</I>]
</P>

<P>
<DEL>An</DEL> <INS>Otherwise, an</INS> expression E can be
explicitly converted to a type T if there is an implicit conversion
sequence (12.2.4.2 [<A href="https://wg21.link/over.best.ics">over.best.ics</A>]) from E to T, if overload
resolution ...</P>

<P class="del">Otherwise, the static_cast shall perform one of the
conversions listed below. No other conversion shall be performed
explicitly using a static_cast.</P>

<P class="del">Any expression can be explicitly converted to type cv
void, in which case the operand is a discarded-value expression
(7.2 [<A href="https://wg21.link/expr.prop">expr.prop</A>]).  [<I>Note 3:</I> Such a static_cast has no
result as it is a prvalue of type void; see
7.2.1 [<A href="https://wg21.link/basic.lval">basic.lval</A>]. &#8212;<I>end note</I>]
[<I>Note 4:</I> However, if the value is in a temporary
object (6.7.7 [<A href="https://wg21.link/class.temporary">class.temporary</A>]), the destructor for that object is
not executed until the usual time, and the value of the object is
preserved for the purpose of executing the destructor. &#8212;<I>end
note</I>]
</P>

<P>
<DEL>The</DEL> <INS>Otherwise, the</INS> inverse
of <DEL>any</DEL> <INS>a</INS> standard conversion sequence
(7.3 [<A href="https://wg21.link/conv">conv</A>]) not containing an lvalue-to-rvalue
(7.3.2 [<A href="https://wg21.link/conv.lval">conv.lval</A>]), array-to-pointer
(7.3.3 [<A href="https://wg21.link/conv.array">conv.array</A>]), function-to-pointer
(7.3.4 [<A href="https://wg21.link/conv.func">conv.func</A>]), null pointer
(7.3.12 [<A href="https://wg21.link/conv.ptr">conv.ptr</A>]), null member pointer
(7.3.13 [<A href="https://wg21.link/conv.mem">conv.mem</A>]), boolean (7.3.15 [<A href="https://wg21.link/conv.bool">conv.bool</A>]),
or function pointer (7.3.14 [<A href="https://wg21.link/conv.fctptr">conv.fctptr</A>]) conversion, can be
performed explicitly using static_cast. A program is ill-formed if it
uses static_cast to perform the inverse of an ill-formed standard
conversion sequence.
</P>

</BLOCKQUOTE>
</LI>

<LI>
<P>Add a new paragraph after 7.6.1.9 [<A href="https://wg21.link/expr.static.cast#14">expr.static.cast</A>] paragraph 14:</P>

<BLOCKQUOTE>

<P>A prvalue of type &#8220;pointer to cv1 void&#8221; can be
converted to a prvalue of type &#8220;pointer to cv2 T&#8221;, ...
Otherwise, the pointer value is unchanged by the conversion.
[<I>Example 3:</I> ...  &#8212;<I>end example</I>]
</P>

<P class="ins">
No other conversion can be performed using <TT>static_cast</TT>.
</P>

</BLOCKQUOTE>

</LI>
</OL>

<BR><BR><HR>
<A NAME="2883"></A><H4>2883.
  
Definition of "odr-usable" ignores lambda scopes
</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>Hubert Tong
 &#160;&#160;&#160;

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


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

<P>Consider:</P>

<PRE>
  void f() {
    int x;
    [&amp;] {
      return x;       //<SPAN CLASS="cmnt"> #1</SPAN>
    };
  }
</PRE>

<P>The odr-use of <TT>x</TT> is ill-formed, because <TT>x</TT> is not
odr-usable in that scope, because there is a lambda scope
(6.4.5 [<A href="https://wg21.link/basic.scope.lambda">basic.scope.lambda</A>]) between #1 and the definition of
<TT>x</TT>.</P>

<P>A more involved example exhibits implementation divergence:</P>

<PRE>
  struct A {
    A() = default;
    A(const A &amp;) = delete;
    constexpr operator int() { return 42; }
  };
  void f() {
    constexpr A a;
    [=]&lt;typename T, int = a&gt; {};   //<SPAN CLASS="cmnt"> OK, not odr-usable from a default template argument, and not odr-used</SPAN>
  }
</PRE>

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

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

<BLOCKQUOTE>

A local entity (6.1 [<A href="https://wg21.link/basic.pre">basic.pre</A>]) is <I>odr-usable</I> in a
scope (6.4.1 [<A href="https://wg21.link/basic.scope.scope">basic.scope.scope</A>]) if:
<UL>
<LI> either the local entity
is not *this, or an enclosing class or non-lambda function parameter
scope exists and, if the innermost such scope is a function parameter
scope, it corresponds to a non-static member function, and</LI>
<LI>for each intervening scope (6.4.1 [<A href="https://wg21.link/basic.scope.scope">basic.scope.scope</A>]) between
the point at which the entity is introduced and the scope (where *this
is considered to be introduced within the innermost enclosing class or
non-lambda function definition scope), either:
<UL>
<LI>the intervening scope is a block scope, or</LI>

<LI>the intervening scope is the function parameter scope of
a <I>lambda-expression</I><INS>, or</INS>
</LI>

<LI>
<INS>the intervening scope is the lambda scope of
a <I>lambda-expression</I></INS> that has a <I>simple-capture</I>
naming the entity or has a <I>capture-default</I>, and the block scope
of the <I>lambda-expression</I> is also an intervening scope.
</LI>
</UL>
</LI>
</UL>
If a local entity is odr-used in a scope in which it is not
odr-usable, the program is ill-formed.

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2886"></A><H4>2886.
  
Temporaries and trivial potentially-throwing special member functions
</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>Jiang An
 &#160;&#160;&#160;

 <B>Date: </B>2024-04-27




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

<P>Paper P1286R2 (Contra CWG DR1778) allowed trivial
potentially-throwing special member functions.  Whether such a trivial
special member function is actually invoked is thus observable via
the <TT>noexcept</TT> operator. Issue 2820
clarified the situation for value-initialization and removed a special
case for a trivial default constructor.</P>

<P>Subclause 6.7.7 [<A href="https://wg21.link/class.temporary#4">class.temporary</A>] paragraph 4 appears to
normatively avoid invoking a trivial constructor or destructor,
something best left to the as-if rule.  There is implementation
divergence for this example:</P>

<PRE>
  struct C {
    C() = default;
    ~C() noexcept(false) = default;
  };

  static_assert(noexcept(C()));
</PRE>

<P>A related question arises from the introduction of temporaries for
function parameters and return values in 6.7.7 [<A href="https://wg21.link/class.temporary#3">class.temporary</A>] paragraph 3.  However, this situation can never result in actually
throwing an exception during forward evolution: when the constructor
becomes non-trivial, the permission to create a temporary object
evaporates.</P>

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

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

<BLOCKQUOTE>

When an object of class type X is passed to or returned from a
<INS>potentially-evaluated</INS> function <INS>call</INS>, if X has at
least one eligible copy or move constructor
(11.4.4 [<A href="https://wg21.link/special">special</A>]), each such constructor is trivial, and
the destructor of X is either trivial or deleted, implementations are
permitted to create a temporary object to hold the function parameter
or result object. The temporary object is constructed from the
function argument or return value, respectively, and the function's
parameter or return object is initialized as if by using the eligible
trivial constructor to copy the temporary (even if that constructor is
inaccessible or would not be selected by overload resolution to
perform a copy or move of the object).

</BLOCKQUOTE>
</LI>

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

<BLOCKQUOTE>

<DEL>When an implementation
introduces a temporary object of a
class that has a non-trivial constructor
(11.4.5.2 [<A href="https://wg21.link/class.default.ctor">class.default.ctor</A>], 11.4.5.3 [<A href="https://wg21.link/class.copy.ctor">class.copy.ctor</A>]),
it shall ensure that a constructor is
called for the temporary object. Similarly, the destructor shall
be called for a temporary with a non-trivial destructor
(11.4.7 [<A href="https://wg21.link/class.dtor">class.dtor</A>]).</DEL> Temporary objects are destroyed
as the last step in evaluating the full-expression
(6.9.1 [<A href="https://wg21.link/intro.execution">intro.execution</A>]) that (lexically) contains the point where
they were created. This is true even if that evaluation ends in
throwing an exception. The value computations and side effects of
destroying a temporary object are associated only with the
full-expression, not with any specific subexpression.

</BLOCKQUOTE>

</LI>
</OL>

<BR><BR><HR>
<A NAME="2887"></A><H4>2887.
  
Missing compatibility entries for xvalues
</H4>
<B>Section: </B>C.6.3&#160; [<A href="https://wg21.link/diff.cpp03.expr">diff.cpp03.expr</A>]
 &#160;&#160;&#160;

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

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

 <B>Date: </B>2024-04-18


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

<P>Paper N3055 (A Taxonomy of Expression Value Categories) introduced
xvalues.  This changed the behavior of well-formed code
for <TT>typeid</TT> and the conditional operator, but corresponding
entries in Annex C are missing.</P>

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

<OL>
<LI>
<P>Add a new paragraph to C.6.3 [<A href="https://wg21.link/diff.cpp03.expr">diff.cpp03.expr</A>] as follows:</P>

<BLOCKQUOTE class="ins">

<B>Affected subclause:</B> 7.6.1.8 [<A href="https://wg21.link/expr.typeid">expr.typeid</A>]<BR>
<B>Change:</B> Evaluation of operands in <TT>typeid</TT>.<BR>
<B>Rationale:</B> Introduce additional expression value categories.<BR>
<B>Effect on original feature:</B> Valid C++ 2003 code that uses
xvalues as operands for <TT>typeid</TT> may change behavior. For
example,<BR>

<PRE>
  void f() {
    struct B {
      B() {}
      virtual ~B() { }
    };

    struct C { B b; };
    typeid(C().b); //<SPAN CLASS="cmnt"> unevaluated in C++03, evaluated in C++11</SPAN>
  }
</PRE>
</BLOCKQUOTE>
</LI>

<LI>
<P>Add a new paragraph to C.6.3 [<A href="https://wg21.link/diff.cpp03.expr">diff.cpp03.expr</A>] as follows:</P>

<BLOCKQUOTE class="ins">

<B>Affected subclause:</B> 7.6.16 [<A href="https://wg21.link/expr.cond">expr.cond</A>]<BR>
<B>Change:</B> Fewer copies in the conditional operator.<BR>
<B>Rationale:</B> Introduce additional expression value categories.<BR>
<B>Effect on original feature:</B> Valid C++ 2003 code that uses
xvalues as operands for the conditional operator may change behavior. For
example,<BR>

<PRE>
  void f() {
    struct B {
      B() {}
      B(const B&amp;) { }
    };
    struct D : B {};

    struct BB { B b; };
    struct DD { D d; };

    true ? BB().b : DD().d; //<SPAN CLASS="cmnt"> additional copy in C++03, no copy or move in C++11</SPAN>
  }
</PRE>
</BLOCKQUOTE>
</LI>

</OL>

<BR><BR><HR>
<A NAME="2891"></A><H4>2891.
  
Normative status of implementation limits
</H4>
<B>Section: </B>Clause Annex B&#160; [<A href="https://wg21.link/implimits">implimits</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>ISO/CS
 &#160;&#160;&#160;

 <B>Date: </B>2024-05-17


<P>It is unclear whether Clause Annex B [<A href="https://wg21.link/implimits">implimits</A>] is normative,
and what its normative content is.  The Annex was
<A HREF="https://github.com/cplusplus/draft/commit/7e66cc0c7d0c4fea57fff2c283dd0900d6333f8e">editorially switched</A>
from "informative" to "normative" in September 2020 with this change
description:</P>

<BLOCKQUOTE>
<P>[intro.compliance.general, implimits] Cite Annex B normatively.</P>

<P>This change also promotes Annex B [implimits] to a "normative"
annex.  The existing wording in the annex is already normative in
character.</P>
</BLOCKQUOTE>

<P>On the other hand, this sentence in Clause Annex B [<A href="https://wg21.link/implimits#2">implimits</A>] paragraph 2 seems to say otherwise:</P>

<BLOCKQUOTE>

... However, these quantities are only guidelines and do not determine
compliance.

</BLOCKQUOTE>

<P>If it is indeed intentional that the actual quantitative limits are
just guidelines, then the normative (conformance-related) content is
limited to Clause Annex B [<A href="https://wg21.link/implimits#1">implimits</A>] paragraph 1, which establishes
documentation requirements only:</P>

<BLOCKQUOTE>

Because computers are finite, C++ implementations are inevitably
limited in the size of the programs they can successfully
process. Every implementation shall document those limitations where
known. This documentation may cite fixed limits where they exist, say
how to compute variable limits as a function of available resources,
or say that fixed limits do not exist or are unknown.

</BLOCKQUOTE>

<P>However, those general documentation requirements are best
expressed in 4.1.1 [<A href="https://wg21.link/intro.compliance.general">intro.compliance.general</A>], leaving
Clause Annex B [<A href="https://wg21.link/implimits">implimits</A>] with just an informative list of minimum
suggested quantities.</P>

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

<OL>

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

<BLOCKQUOTE>

If a program contains no violations of the rules in Clause 5 through
Clause 33 and Annex D, a conforming implementation shall, within its
resource limits <DEL>as described in Annex B</DEL> <INS>(see
below)</INS>, accept and correctly execute that program.

</BLOCKQUOTE>
</LI>

<LI>
<P>Insert a new paragraph before 4.1.1 [<A href="https://wg21.link/intro.compliance.general#8">intro.compliance.general</A>] paragraph 8 as follows:</P>

<BLOCKQUOTE>

<P class="ins">
An implementation shall document its limitations in the size of the
programs it can successfully process, where known. This documentation
may cite fixed limits where they exist, say how to compute variable
limits as a function of available resources, or say that fixed limits
do not exist or are unknown. Clause Annex B [<A href="https://wg21.link/implimits">implimits</A>] lists some
quantities that can be subject to limitations, and recommends a
minimum value for each quantity.
</P>

<P>A conforming implementation may have extensions (including additional
library functions), ...</P>

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in Clause Annex B [<A href="https://wg21.link/implimits#1">implimits</A>] paragraph 1 and paragraph 2 as
follows:</P>

<BLOCKQUOTE>

<P>Annex B<BR>
(<DEL>normative</DEL><INS>informative</INS>)</P>

<P class="del">Because computers are finite, C++ implementations are inevitably
limited in the size of the programs they can successfully
process. Every implementation shall document those limitations where
known. This documentation may cite fixed limits where they exist, say
how to compute variable limits as a function of available resources,
or say that fixed limits do not exist or are unknown.</P>

<P>
<DEL>The limits may
constrain quantities that include those described below or others.</DEL>
<INS>Implementations can exhibit limitations, among others
for the quantities in the following list.</INS>
The bracketed number
following each quantity is recommended as the minimum <INS>value</INS>
for that quantity.
<DEL>However, these quantities are only guidelines and do not
determine compliance.</DEL>
</P>

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

<P><B>CWG 2024-05-17</B></P>

<P>CWG was divided whether to relax the documentation requirement or
not.  As a next step, the wording for a relaxation should be
reviewed.</P>

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

<OL>

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

<BLOCKQUOTE>

If a program contains no violations of the rules in Clause 5 through
Clause 33 and Annex D, a conforming implementation shall<DEL>, within
its resource limits as described in Annex B,</DEL> accept and
correctly execute that program<INS>, except when the implementation's
limitations (see below) are exceeded</INS>.

</BLOCKQUOTE>
</LI>

<LI>
<P>Insert a new paragraph before 4.1.1 [<A href="https://wg21.link/intro.compliance.general#8">intro.compliance.general</A>] paragraph 8 as follows:</P>

<BLOCKQUOTE>

<P class="ins">
An implementation is encouraged to document its limitations in the
size or complexity of the programs it can successfully process, if
possible and where known. Clause Annex B [<A href="https://wg21.link/implimits">implimits</A>] lists some
quantities that can be subject to limitations and a potential minimum
supported value for each quantity.
</P>

<P>A conforming implementation may have extensions (including additional
library functions), ...</P>

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in Clause Annex B [<A href="https://wg21.link/implimits#1">implimits</A>] paragraph 1 and paragraph 2 as
follows:</P>

<BLOCKQUOTE>

<P>Annex B<BR>
(<DEL>normative</DEL><INS>informative</INS>)</P>

<P class="del">Because computers are finite, C++ implementations are inevitably
limited in the size of the programs they can successfully
process. Every implementation shall document those limitations where
known. This documentation may cite fixed limits where they exist, say
how to compute variable limits as a function of available resources,
or say that fixed limits do not exist or are unknown.</P>

<P>
<DEL>The limits may
constrain quantities that include those described below or others.</DEL>
<INS>Implementations can exhibit limitations for various quantities;
some possibilities are presented in the following list.</INS> The
bracketed number following each quantity is <DEL>recommended as
the</DEL> <INS>a potential</INS> minimum <INS>value</INS> for that
quantity.
<DEL>However, these quantities are only guidelines and do not
determine compliance.</DEL>
</P>

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

<BR><BR><HR>
<A NAME="2892"></A><H4>2892.
  
Unclear usual arithmetic conversions
</H4>
<B>Section: </B>7.4&#160; [<A href="https://wg21.link/expr.arith.conv">expr.arith.conv</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Lauri Vasama
 &#160;&#160;&#160;

 <B>Date: </B>2024-05-06


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

<P>Subclause 7.4 [<A href="https://wg21.link/expr.arith.conv#1.4.1">expr.arith.conv</A>] bullet 1.4.1 specifies:</P>

<BLOCKQUOTE>

<UL>
<LI>If both operands have the same type, no further conversion is
needed.</LI>
</UL>

</BLOCKQUOTE>

<P>What does "needed" mean?</P>

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

<P>Change in 7.4 [<A href="https://wg21.link/expr.arith.conv#1.4.1">expr.arith.conv</A>] bullet 1.4.1 as follows:</P>

<BLOCKQUOTE>

<UL>
<LI>If both operands have the same type, no further conversion is
<DEL>needed</DEL> <INS>performed</INS>.</LI>
</UL>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2895"></A><H4>2895.
  
Initialization should ignore the destination type's cv-qualification
</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>Brian Bi
 &#160;&#160;&#160;

 <B>Date: </B>2024-05-29


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

<P>Initialization of <I>cv</I> <TT>T</TT> follows the same rules as
initialization of <TT>T</TT>.  Issue 2830
clarified this for list-initialization.  Further amendments are needed
to properly handle cv-qualified versions of <TT>char8_t</TT>
and <TT>char16_t</TT> as well as <TT>bool</TT>.</P>

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

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

<BLOCKQUOTE>

The semantics of initializers are as follows. The destination type is
the <INS>cv-unqualified</INS> type of the object or reference being
initialized and the source type is the type of the initializer
expression. If the initializer is not a single (possibly
parenthesized) expression, the source type is not defined.

</BLOCKQUOTE>
</LI>

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

<BLOCKQUOTE>

<UL>
<LI>
Otherwise, if the destination type is a <DEL>(possibly
cv-qualified)</DEL> class type:
<UL>
<LI>
If the initializer expression is a prvalue and the cv-unqualified
version of the source type is the same <DEL>class as the class
of</DEL> <INS>as</INS> the destination <INS>type</INS>, the
initializer expression is used to initialize the destination object.
[<I>Example 2:</I> T x = T(T(T())); value-initializes x. &#8212;<I>end
example</I>]
</LI>

<LI>
Otherwise, if the initialization is direct-initialization, or if it is
copy-initialization where the cv-unqualified version of the source
type is the same <DEL>class as, or a derived class of, the class of</DEL>
<INS>as or is derived from</INS> the destination <INS>type</INS>,
constructors are considered. The applicable constructors are
enumerated (12.2.2.4 [<A href="https://wg21.link/over.match.ctor">over.match.ctor</A>]), and the best one is chosen
through overload resolution (12.2 [<A href="https://wg21.link/over.match">over.match</A>]). Then:
</LI>

</UL>
</LI>
</UL>
</BLOCKQUOTE>
</LI>

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

<BLOCKQUOTE>

<UL>
<LI>
Otherwise, the initial value of the object being initialized is the
(possibly converted) value of the initializer expression. A standard
conversion sequence (7.3 [<A href="https://wg21.link/conv">conv</A>]) is used to convert the
initializer expression to a prvalue of <DEL>the cv-unqualified version
of</DEL> the destination type; no user-defined conversions are
considered. If the conversion cannot be done, the initialization is
ill-formed. When initializing a bit-field with a value that it cannot
represent, the resulting value of the bit-field is
implementation-defined.  [ Note: ... ]
</LI>
</UL>

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

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