<HTML>
<HEAD>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<TITLE>
    Core "ready" Issues
   </TITLE>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<STYLE TYPE="text/css">
  INS { text-decoration:none; font-weight:bold; background-color:#A0FFA0 }
  .INS { text-decoration:none; background-color:#D0FFD0 }
  DEL { text-decoration:line-through; background-color:#FFA0A0 }
  .DEL { text-decoration:line-through; background-color: #FFD0D0 }
  @media (prefers-color-scheme: dark) {
    HTML { background-color:#202020; color:#f0f0f0; }
    A { color:#5bc0ff; }
    A:visited { color:#c6a8ff; }
    A:hover, a:focus { color:#afd7ff; }
    INS { background-color:#033a16; color:#aff5b4; }
    .INS { background-color: #033a16; }
    DEL { background-color:#67060c; color:#ffdcd7; }
    .DEL { background-color:#67060c; }
  }
  SPAN.cmnt { font-family:Times; font-style:italic }
</STYLE>
</HEAD>
<BODY>
<TABLE ALIGN="RIGHT" CELLSPACING="0" CELLPADDING="0">
<TR>
<TD ALIGN="RIGHT">
      Document number:
     </TD>
<TD>
       &#160;N3752R0</TD>
</TR>
<TR>
<TD ALIGN="RIGHT">
      Date:
     </TD>
<TD>
      &#160;2025-06-20</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 14882:2024
     </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, 2025 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/n5001.pdf">WG21 N5008</A>.
   </P>
<HR>
<A NAME="2843"></A><H4>2843.
  
Undated reference to Unicode makes C++ a moving target
</H4>
<B>Section: </B>Clause 2&#160; [<A href="https://wg21.link/intro.refs">intro.refs</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Jonathan Wakely
 &#160;&#160;&#160;

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




<P>Clause 2 [<A href="https://wg21.link/intro.refs#1.10">intro.refs</A>] paragraph 1.10 uses an undated reference for
the Unicode standard, meaning that a published (and otherwise frozen)
standard for C++ (e.g. C++23) will implicitly refer to a new revision
of the Unicode standard the moment such is issued:</P>

<BLOCKQUOTE>

... For undated references, the latest edition of the referenced document
(including any amendments) applies.

<UL>
<LI>...</LI>
<LI>The Unicode Consortium. The Unicode Standard. Available from:
<TT>https://www.unicode.org/versions/latest/</TT>
</LI>
</UL>

</BLOCKQUOTE>

<P>This situation is strictly worse than the lack of support for
certain scripts or languages, which can be rectified by updating the
reference to Unicode in the next revision of the C++ standard, as is
regularly done with any other missing language feature deemed worth
addressing.</P>

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

<P>Change in Clause 2 [<A href="https://wg21.link/intro.refs#1.10">intro.refs</A>] paragraph 1.10 as follows:</P>

<UL>
<LI>...</LI>
<LI>The Unicode Consortium. The Unicode Standard<INS>, Version 15.0</INS>. Available from:
<TT><DEL>https://www.unicode.org/versions/latest/</DEL><INS>https://www.unicode.org/versions/Unicode15.0.0/</INS></TT>
</LI>
</UL>

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

<P>Forwarded to SG16 and LWG by decision of the CWG chair, via
<A HREF="https://github.com/cplusplus/papers/issues/1736">paper issue 1736</A>.</P>

<P><B>SG16 2024-01-10</B></P>

<P>SG16 has consensus to have a dated reference to Unicode in the
"Normative references", indicating a minimum version, and add
permission to implement an implementation-defined later version.</P>

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

<OL>
<LI>
<P>Change in Clause 2 [<A href="https://wg21.link/intro.refs#1.10">intro.refs</A>] paragraph 1.10 as follows:</P>

<UL>
<LI>...</LI>
<LI>The Unicode Consortium. The Unicode Standard<INS>, Version 15.0</INS>. Available from:
<TT><DEL>https://www.unicode.org/versions/latest/</DEL><INS>https://www.unicode.org/versions/Unicode15.0.0/</INS></TT>
</LI>
</UL>
</LI>

<LI>
<P>Add a 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">
A conforming implementation may implement an implementation-defined
version of the Unicode Standard that is a later version than the one
referenced in Clause 2 [<A href="https://wg21.link/intro.refs">intro.refs</A>].
</P>

<P>A conforming implementation may have extensions (including additional
library functions), provided they do not alter the behavior of any
well-formed program.</P>

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

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

<P>CWG took note of the issue.  No objections were raised regarding
the suggested direction.</P>

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

<P>Allow implementation-defined Unicode version, but require at least
version 15.1.</P>

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

<OL>
<LI>
<P>Change in Clause 2 [<A href="https://wg21.link/intro.refs#1.10">intro.refs</A>] paragraph 1.10 as follows:</P>

<UL>
<LI>...</LI>
<LI>The Unicode Consortium. The Unicode Standard<INS>, Version 15.1</INS>. Available from:
<TT><DEL>https://www.unicode.org/versions/latest/</DEL><INS>https://www.unicode.org/versions/Unicode15.1.0/</INS></TT>
</LI>
</UL>
</LI>

<LI>
<P>Add a 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">
A conforming implementation may implement an implementation-defined
version of the Unicode Standard that is a later version than the one
referenced in Clause 2 [<A href="https://wg21.link/intro.refs">intro.refs</A>].
</P>

<P>A conforming implementation may have extensions (including additional
library functions), provided they do not alter the behavior of any
well-formed program.</P>

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

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

<P>More drafting to rebase Annex E on Unicode 15.1 is needed.</P>

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

<P>See also P3727R0.</P>

<P><B>Proposed resolution (approved by CWG 2025-06-20):</B></P>

<OL>
<LI>
<P>Change in Clause 2 [<A href="https://wg21.link/intro.refs#1.10">intro.refs</A>] paragraph 1.10 as follows:</P>

<UL>
<LI>...</LI>
<LI>The Unicode Consortium. The Unicode Standard<INS>, Version 15.1</INS>. Available from:
<TT><DEL>https://www.unicode.org/versions/latest/</DEL><INS>https://www.unicode.org/versions/Unicode15.1.0/</INS></TT>
</LI>
</UL>
</LI>

<LI>
<P>Add a 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">
A conforming implementation may use an implementation-defined
version of the Unicode Standard that is a later version than the one
referenced in Clause 2 [<A href="https://wg21.link/intro.refs">intro.refs</A>].
</P>

<P>A conforming implementation may have extensions (including additional
library functions), provided they do not alter the behavior of any
well-formed program.</P>

</BLOCKQUOTE>
</LI>

<LI>
<P>Remove E.2.2 [<A href="https://wg21.link/uaxid.def.rfmt">uaxid.def.rfmt</A>]:</P>

<BLOCKQUOTE class="del">

<P>E.2.2 1 R1a Restricted format characters [uaxid.def.rfmt]</P>

<P>If an implementation of UAX #31 wishes to allow format characters
such as u+200d zero width joiner or u+200c zero width non-joiner it
must define a profile allowing them, or describe precisely which
combinations are permitted.</P>

<P>C++ does not allow format characters in identifiers, so this does
not apply.</P>

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

<BR><BR><HR>
<A NAME="2898"></A><H4>2898.
  
Clarify implicit conversion sequence from <I>cv</I> <TT>T</TT> to <TT>T</TT>
</H4>
<B>Section: </B>12.2.4.2.1&#160; [<A href="https://wg21.link/over.best.ics.general">over.best.ics.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-30


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

<P>Subclause 12.2.4.2.1 [<A href="https://wg21.link/over.best.ics.general#7">over.best.ics.general</A>] paragraph 7 specifies:</P>

<BLOCKQUOTE>

When the parameter has a class type and the argument expression has
the same type, the implicit conversion sequence is an identity
conversion. When the parameter has a class type and the argument
expression has a derived class type, the implicit conversion sequence
is a derived-to-base conversion from the derived class to the base
class. A derived-to-base conversion has Conversion rank
(12.2.4.2.2 [<A href="https://wg21.link/over.ics.scs">over.ics.scs</A>]).

</BLOCKQUOTE>

<P>Does "the same type" imply that differences in cv-qualification are
significant?  12.2.4.2.1 [<A href="https://wg21.link/over.best.ics.general#6">over.best.ics.general</A>] paragraph 6 appears to
differ:</P>

<BLOCKQUOTE>

... Any difference in top-level cv-qualification is subsumed by the
initialization itself and does not constitute a conversion. [Example
2: A parameter of type A can be initialized from an argument of type
const A. The implicit conversion sequence for that case is the
identity sequence; it contains no "conversion" from const A to A. --
end example]

</BLOCKQUOTE>

<P>The example appears to reflect the intent; the normative wording
should be clarified.</P>

<P><B>Proposed resolution (no objections during CWG reflector review starting 2025-03-11):</B></P>

<OL>
<LI>
<P>Change in 12.2.4.2.1 [<A href="https://wg21.link/over.best.ics.general#6">over.best.ics.general</A>] paragraph 6, moving the
amended example to paragraph 7:</P>

<BLOCKQUOTE>

... <DEL>Any difference in top-level cv-qualification is subsumed by the
initialization itself and does not constitute a conversion. [Example
2: A parameter of type A can be initialized from an argument of type
const A. The implicit conversion sequence for that case is the
identity sequence; it contains no "conversion" from const A to A. --
end example]</DEL>

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 12.2.4.2.1 [<A href="https://wg21.link/over.best.ics.general#7">over.best.ics.general</A>] paragraph 7 as follows:</P>

<BLOCKQUOTE>

When <DEL>the parameter has a class type and the argument expression
has the same type</DEL> <INS>the cv-unqualified version of the type of
the argument expression is the same as the parameter type</INS>, the
implicit conversion sequence is an identity conversion. When the
parameter has a class type and the argument expression has
a <INS>(possibly cv-qualified)</INS> derived class type, the implicit
conversion sequence is a derived-to-base conversion from the derived
class to the base class. A derived-to-base conversion has Conversion
rank (12.2.4.2.2 [<A href="https://wg21.link/over.ics.scs">over.ics.scs</A>]).
<INS>[Example: An implicit conversion sequence from an argument of
type const A to a parameter of type A can be formed, even if overload
resolution for copy-initialization of A from the argument would not
find a viable function (12.2.2.4 [<A href="https://wg21.link/over.match.ctor">over.match.ctor</A>],
12.2.3 [<A href="https://wg21.link/over.match.viable">over.match.viable</A>]). The implicit conversion sequence for
that case is the identity sequence; it contains no "conversion" from
const A to A. -- end example]</INS>
</BLOCKQUOTE>
</LI>
</OL>

<BR><BR><HR>
<A NAME="2982"></A><H4>2982.
  
Deduction in <I>type-constraint</I>s
</H4>
<B>Section: </B>13.10.3.7&#160; [<A href="https://wg21.link/temp.deduct.decl">temp.deduct.decl</A>]
 &#160;&#160;&#160;

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

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

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




<P>Consider:</P>

<PRE>
  template&lt;typename T, typename U&gt; concept C = true;
  template&lt;typename T&gt; C&lt;T&gt; auto f() { return 0; }
  template C&lt;int&gt; auto f();
</PRE>

<P>Is that valid?  Or is the following needed:</P>

<PRE>
  template C&lt;int&gt; auto f&lt;int&gt;();
</PRE>
<P>The specification neither discusses deduction from a
<I>type-constraint</I> nor treating it as a non-deduced context.</P>

<P><B>Proposed resolution (no objections during CWG reflector review starting 2025-03-18) (approved by CWG 2025-06-20):</B></P>

<P>Change in 13.10.3.6 [<A href="https://wg21.link/temp.deduct.type#5">temp.deduct.type</A>] paragraph 5 as follows:</P>

<BLOCKQUOTE>

The non-deduced contexts are:
<UL>
<LI>The <I>nested-name-specifier</I> of a type that was specified
using a <I>qualified-id</I>.</LI>
<LI>A <I>pack-index-specifier</I> or a <I>pack-index-expression</I>.</LI>
<LI class="ins">A <I>type-constraint</I>.</LI>
<LI>The <I>expression</I> of a <I>decltype-specifier</I>.</LI>
<LI>...</LI>
</UL>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2985"></A><H4>2985.
  
Unclear rules for reference initialization with conversion
</H4>
<B>Section: </B>9.5.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>Anoop Rana
 &#160;&#160;&#160;

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


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

<P>It is unclear whether 9.5.4 [<A href="https://wg21.link/dcl.init.ref#5.4.1">dcl.init.ref</A>] bullet 5.4.1
intends list-initialization or not-list-initializaiton when it talks
about direct-initialization.</P>

<P>Furthermore, the following example was well-formed before the
resolution of issue 1604 was applied:</P>

<PRE>
  struct X { };
  
  struct Y : X {};

  struct Z {
    operator const Y () const;
  };
  
  Z z;
  X&amp;&amp; r = z; //<SPAN CLASS="cmnt"> #1, ill-formed; was well-formed before CWG1604</SPAN>
</PRE>

<P><U>Possible resolution (January, 2025) [SUPERSEDED]:</U></P>

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

<BLOCKQUOTE>

If T1 or T2 is a class type, user-defined conversions are considered
using the rules for copy-initialization of an object of type
&#8220;cv1 T1&#8221; by user-defined conversion
(9.5 [<A href="https://wg21.link/dcl.init">dcl.init</A>], 12.2.2.5 [<A href="https://wg21.link/over.match.copy">over.match.copy</A>],
12.2.2.6 [<A href="https://wg21.link/over.match.conv">over.match.conv</A>]); the program is ill-formed if the
corresponding non-reference copy-initialization would be
ill-formed. The result <INS>E</INS> of the call to the conversion
function, as described for the non-reference copy-initialization, is
then used to direct-initialize the reference <INS>using the form <TT>(
E )</TT>; if <INS>E</INS> is a prvalue, its cv-qualification is
adjusted to <I>cv1</I></INS>. For this direct-initialization,
user-defined conversions are not considered.

</BLOCKQUOTE>

<P><B>Additional notes (February, 2025)</B></P>

<P>Permitting a binding of <TT>X&amp;&amp;</TT> to a <TT>const Y</TT>
seems ill-advised; the change effected by issue 1604 in that regard is intended.</P>

<P>In more detail, copy-initializing a T object from a cv T prvalue
succeeds:</P>

<PRE>
  struct X { X() = default; X(X&amp;&amp;) = delete; };
  using CX = const X;
  X x = CX();    //<SPAN CLASS="cmnt"> OK, default-initializes </SPAN>x
</PRE>

<P>However, even with guaranteed copy elision, the pre-CWG1604 model
does not handle derived classes appropriately when reference binding:</P>

<PRE>
  struct X {
    X() = default;
    X(X&amp;&amp;) = delete;
  };
  struct Y : X {};
  struct Z {
    operator Y() { return Y(); }
  };
  X&amp;&amp; x = Z();
</PRE>

<P>In this case, the rvalue reference <TT>x</TT> should bind directly
to the <TT>Y</TT> materialized prvalue; there should never be an
attempt to copy-initialize an <TT>X</TT> from <TT>Z</TT> to satisfy
the reference binding.  However, such direct reference binding would
not be expected to work for a <TT>const Y</TT> prvalue.</P>

<P><B>Proposed resolution (February, 2025) (approved by CWG 2025-06-20):</B></P>

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

<BLOCKQUOTE>

If T1 or T2 is a class type, user-defined conversions are considered
using the rules for copy-initialization of an object of type
&#8220;cv1 T1&#8221; by user-defined conversion
(9.5 [<A href="https://wg21.link/dcl.init">dcl.init</A>], 12.2.2.5 [<A href="https://wg21.link/over.match.copy">over.match.copy</A>],
12.2.2.6 [<A href="https://wg21.link/over.match.conv">over.match.conv</A>]); the program is ill-formed if the
corresponding non-reference copy-initialization would be
ill-formed. The result <INS>E</INS> of the call to the conversion
function, as described for the non-reference copy-initialization, is
then used to direct-initialize the reference <INS>using the form <TT>(
E )</TT></INS>. For this direct-initialization,
user-defined conversions are not considered.

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2987"></A><H4>2987.
  
Remove dilapidated wording from <TT>static_cast</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>Brian Bi
 &#160;&#160;&#160;

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




<P>There is some ancient non-operational wording in
7.6.1.9 [<A href="https://wg21.link/expr.static.cast">expr.static.cast</A>].  It should be removed.</P>

<P><B>Proposed resolution (no objections during CWG reflector review starting 2025-03-04) (approved by CWG 2025-06-20):</B></P>

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

<BLOCKQUOTE>

The result of the expression static_cast&lt;T&gt;(v) is the result of
converting the expression v to type T. If T is an lvalue reference
type or an rvalue reference to function type, the result is an lvalue;
if T is an rvalue reference to object type, the result is an xvalue;
otherwise, the result is a prvalue. <DEL>The static_cast operator shall not
cast away constness (7.6.1.11 [<A href="https://wg21.link/expr.const.cast">expr.const.cast</A>]).</DEL>

</BLOCKQUOTE>
</LI>

<LI>
<P>Remove 7.6.1.9 [<A href="https://wg21.link/expr.static.cast#6">expr.static.cast</A>] paragraph 6:</P>

<BLOCKQUOTE class="del">

Otherwise, the inverse of a 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.  [<I>Example 2:</I>
<PRE>
  struct B { };
  struct D : private B { };
  void f() {
  static_cast&lt;D*&gt;((B*)0);
  static_cast&lt;int B::*&gt;((int D::*)0);
  }
</PRE>
&#8212;<I>end example</I>]
</BLOCKQUOTE>

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

<BLOCKQUOTE>

<DEL>The</DEL> <INS>Otherwise, the</INS> 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>]) conversions are applied to the
operand<INS>, and the conversions that can be performed
using <TT>static_cast</TT> are listed below</INS>. <INS>No other
conversion can be performed
using <TT>static_cast</TT>.</INS> <DEL>Such a static_cast is subject
to the restriction that the explicit conversion does not cast away
constness (7.6.1.11 [<A href="https://wg21.link/expr.const.cast">expr.const.cast</A>]), and the following
additional rules for specific cases:</DEL>

</BLOCKQUOTE>
</LI>

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

<BLOCKQUOTE class="del">

No other conversion can be performed using static_cast.

</BLOCKQUOTE>
</LI>
</OL>
<BR><BR><HR>
<A NAME="3013"></A><H4>3013.
  
Disallowing macros for <TT>#embed</TT> parameters
</H4>
<B>Section: </B>15.4.1&#160; [<A href="https://wg21.link/cpp.embed.gen">cpp.embed.gen</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Hubert Tong
 &#160;&#160;&#160;

 <B>Date: </B>2025-02-15




<P>Subclause 16.4.5.3.3 [<A href="https://wg21.link/macro.names#2">macro.names</A>] paragraph 2 specifies a
prohibition against keywords, alternative tokens, and attributes being
used as macro names.  There is no such protection for parameter names
of <TT>#embed</TT>, but the use of <I>embed-parameter</I>s should be
protected there and in the <TT>__has_embed</TT> argument.</P>

<P>Arguably, 16.4.5.3.3 [<A href="https://wg21.link/macro.names">macro.names</A>] constrains only programs
that use the standard library, because header files of the standard
library must be able to rely on a sane environment; see also
16.4.5.3.1 [<A href="https://wg21.link/reserved.names.general">reserved.names.general</A>]:</P>

<BLOCKQUOTE>

The C++ standard library reserves the following kinds of names: ...

</BLOCKQUOTE>

<P>Arguably, standard library headers can be crafted or auto-generated
such that they do not make use of <TT>#embed</TT>, or at least not
use <TT>#embed</TT> with parameters.  In any case, this would be a
concern of the standard library, not of the core language.</P>

<P><B>Proposed resolution (approved by CWG 2025-06-20):</B></P>

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

<BLOCKQUOTE>

<INS>If one of the <I>pp-tokens</I> of a <TT>#embed</TT> directive
(before macro replacement) is the <I>identifier</I>
<TT>limit</TT>, <TT>prefix</TT>, <TT>suffix</TT>, or
<TT>if_empty</TT> and that <I>identifier</I> is defined as a macro
(15.7.1 [<A href="https://wg21.link/cpp.replace.general">cpp.replace.general</A>]), the program is ill-formed.</INS>
Any <I>embed-prefixed-parameter</I> is conditionally-supported, with
implementation-defined semantics.

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 15.2 [<A href="https://wg21.link/cpp.cond#11">cpp.cond</A>] paragraph 11 as follows:</P>

<BLOCKQUOTE>

Prior to evaluation, macro invocations in the list of preprocessing
tokens that will become the controlling constant expression are
replaced (except for those macro names modified by the defined unary
operator), just as in normal text.
<INS>If replacement of macros in the preprocessing tokens following
the sequence <TT>__has_embed (</TT> and before a matching <TT>)</TT>
(possibly produced by macro expansion) encounters a preprocessing
token that is one of the <I>identifier</I>s <TT>limit</TT>,
<TT>prefix</TT>, <TT>suffix</TT>, or <TT>if_empty</TT> and
that <I>identifier</I> is defined as a macro
(15.7.1 [<A href="https://wg21.link/cpp.replace.general">cpp.replace.general</A>]), the program is ill-formed.</INS> If the
preprocessing token <TT>defined</TT> is generated as a result of this
replacement process or use of the defined unary operator does not
match one of the two specified forms prior to macro replacement, the
behavior is undefined.

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

<BR><BR><HR>
<A NAME="3014"></A><H4>3014.
  
Comma-delimited vs. comma-separated output for <TT>#embed</TT>
</H4>
<B>Section: </B>15.4.1&#160; [<A href="https://wg21.link/cpp.embed.gen">cpp.embed.gen</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Hubert Tong
 &#160;&#160;&#160;

 <B>Date: </B>2025-02-15




<P>Subclause 15.4.1 [<A href="https://wg21.link/cpp.embed.gen#7">cpp.embed.gen</A>] paragraph 7 specifies
"comma-delimited" output for <TT>#embed</TT>.  However, that allows
for a trailing comma that is undesirable.</P>

<P><B>Proposed resolution (approved by CWG 2025-06-20):</B></P>

<P>Change in 15.4.1 [<A href="https://wg21.link/cpp.embed.gen#7">cpp.embed.gen</A>] paragraph 7 and paragraph 8 as follows:</P>

<BLOCKQUOTE>

<P>The #embed directive is replaced by a <DEL>comma-delimited</DEL>
<INS>comma-separated</INS> list of integer literals of type int,
unless otherwise modified by embed parameters
(15.4.2 [<A href="https://wg21.link/cpp.embed.param">cpp.embed.param</A>]).</P>

<P>The integer literals in the <DEL>comma-delimited</DEL>
<INS>comma-separated</INS> list correspond to resource-count
consecutive calls to std::fgetc (31.13.1 [<A href="https://wg21.link/cstdio.syn">cstdio.syn</A>]) from
the resource, as a binary file. If any call to std::fgetc returns EOF,
the program is ill-formed.</P>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="3015"></A><H4>3015.
  
Handling of <I>header-name</I>s for <TT>#include</TT> and <TT>#embed</TT>
</H4>
<B>Section: </B>15.3&#160; [<A href="https://wg21.link/cpp.include">cpp.include</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Jens Maurer
 &#160;&#160;&#160;

 <B>Date: </B>2025-03-23




<P>There is non-parallel treatment for the <I>header-name</I>
in <TT>include</TT> vs. <TT>#embed</TT> directives.</P>

<P>First, subclause 5.5 [<A href="https://wg21.link/lex.pptoken#4.3">lex.pptoken</A>] paragraph 4.3 is missing a
special-case treatment for <TT>#embed</TT>.</P>

<P>Second, 15.3 [<A href="https://wg21.link/cpp.include">cpp.include</A>] (and thus
15.4.1 [<A href="https://wg21.link/cpp.embed.gen">cpp.embed.gen</A>]) should ackowledge that lexing has
completed at that point, and thus talk about <I>header-name</I>
preprocessing tokens, not about sequences of characters.</P>

<P>Third, 15.4.1 [<A href="https://wg21.link/cpp.embed.gen#11">cpp.embed.gen</A>] paragraph 11 talks about "resource
name preprocessing tokens", which do not exist (see
5.5 [<A href="https://wg21.link/lex.pptoken">lex.pptoken</A>]).  Also, it should be clarified this rule
applies to the general <I>pp-tokens</I> form of <TT>#embed</TT>
only.</P>

<P>Fourth, <TT>__has_embed</TT> has this aberration:</P>

<PRE>
  #define stdio nosuch
  #if __has_embed(&lt;stdio.h&gt;)    // looks for nosuch.h
  #embed &lt;stdio.h&gt;              // looks for stdio.h
  #endif
</PRE>

<P>For <TT>__has_include</TT>, this is avoided by using two grammar
productions, where the preferred one uses <I>header-name</I>
(15.2 [<A href="https://wg21.link/cpp.cond">cpp.cond</A>]).</P>

<P>Fifth, for <TT>__has_include</TT>, it is unclear whether only the
first (non-macro-expanded) preprocessing token should be eligible for
special <TT>header-name</TT> treatment.  There is implementation
divergence.</P>

<P>Sixth, for the following example:</P>

<PRE>
  #embed "foo\" vendor_specific_arg("something else") ...
</PRE>
<P>the rule in 5.5 [<A href="https://wg21.link/lex.pptoken#4.3">lex.pptoken</A>] bullet 4.3 would form
a <I>string-literal</I> (because it consists of a longer sequence of
characters), not the <I>header-name</I> <TT>"foo\"</TT>.</P>

<P>Seventh, it is unclear how a <I>q-char-sequence</I> is supposed to
be turned into a <I>h-char-sequence</I> when falling back to header
search in 15.3 [<A href="https://wg21.link/cpp.include#3">cpp.include</A>] paragraph 3, given that
a <I>q-char-sequence</I> might contain a <TT>&gt;</TT> character,
making it not match the production <I>h-char-sequence</I>.</P>

<P><B>Proposed resolution (approved by CWG 2025-06-20):</B></P>

<OL>
<LI>
<P>Change in 5.5 [<A href="https://wg21.link/lex.pptoken#4.3">lex.pptoken</A>] bullet 4.3 and add bullets as follows:</P>

<BLOCKQUOTE>

<UL>
<LI>...</LI>
<LI>Otherwise, the next preprocessing token is the longest sequence of
characters that could constitute a preprocessing token, even if that
would cause further lexical analysis to fail, except that
<UL>
<LI>
a <I>header-name</I> (5.6 [<A href="https://wg21.link/lex.header">lex.header</A>]) is only formed
<UL>
<LI>
<INS>immediately</INS> after the
<TT>include</TT><INS>, <TT>embed,</TT></INS> or <TT>import</TT>
preprocessing token in a <TT>#include</TT>
(15.3 [<A href="https://wg21.link/cpp.include">cpp.include</A>])<INS>,
<TT>#embed</TT> (15.4 [<A href="https://wg21.link/cpp.embed">cpp.embed</A>]),</INS> or import
(15.6 [<A href="https://wg21.link/cpp.import">cpp.import</A>]) directive, <INS>respectively,</INS>
or</LI>
<LI>
<DEL>within a <I>has-include-expression</I></DEL>
<INS>immediately after a preprocessing token sequence of
<TT>__has_include</TT> <INS>or <TT>__has_embed</TT></INS> immediately
followed by <TT>(</TT> in a <TT>#if</TT>, <TT>#elif</TT>,
or <TT>#embed</TT> directive (15.2 [<A href="https://wg21.link/cpp.cond">cpp.cond</A>],
15.4 [<A href="https://wg21.link/cpp.embed">cpp.embed</A>]) and</INS>
</LI>
</UL>
</LI>
<LI>
<INS>a <I>string-literal</I> token is never formed
when a <I>header-name</I> token can be formed</INS>.</LI>
</UL>
</LI>
</UL>
</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 15.2 [<A href="https://wg21.link/cpp.cond">cpp.cond</A>] before paragraph 1:</P>

<BLOCKQUOTE>

<PRE>
  <I>has-embed-expression</I>:
         <INS>__has_embed ( <I>header-name</I> <I>pp-balanced-token-seq</I><SUB>opt</SUB> )</INS>
         __has_embed ( <INS><I>header-name-tokens</I></INS> <I>pp-balanced-token-seq</I><INS><SUB>opt</SUB></INS> )
</PRE>

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 15.2 [<A href="https://wg21.link/cpp.cond#3">cpp.cond</A>] paragraph 3 and paragraph 4 as follows:</P>

<BLOCKQUOTE>

<P class="del">
The second form of <I>has-include-expression</I> is considered only if
the first form does not match, in which case the preprocessing tokens
are processed just as in normal text.
</P>

<P>The header or source file identified by the parenthesized
preprocessing token sequence in each
contained <I>has-include-expression</I> is searched for as if that
preprocessing token sequence were the <I>pp-tokens</I> <DEL>in</DEL>
<INS>of</INS> a <TT>#include</TT> directive, except that no further
macro expansion is performed. If such a directive would not satisfy
the syntactic requirements of a #include directive, the program is
ill-formed.  The <I>has-include-expression</I> evaluates to 1 if the
search for the source file succeeds, and to 0 if the search fails.
</P>

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 15.2 [<A href="https://wg21.link/cpp.cond#5">cpp.cond</A>] paragraph 5 as follows:</P>

<BLOCKQUOTE>
The parenthesized <DEL><I>pp-balanced-token-seq</I> in</DEL>
<INS>preprocessing token sequence of</INS> each contained
<I>has-embed-expression</I> is processed as if that
<DEL><I>pp-balanced-token-seq</I></DEL> <INS>preprocessing token
sequence</INS> were the <I>pp-tokens</I> <DEL>in the third form</DEL>
of a <TT>#embed</TT> directive (15.4 [<A href="https://wg21.link/cpp.embed">cpp.embed</A>])<INS>,
except that no further macro expansion is performed.</INS> If such a
directive would not satisfy the syntactic requirements of a #embed
directive, the program is ill-formed. ...

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 15.3 [<A href="https://wg21.link/cpp.include#1">cpp.include</A>] paragraph 1 through paragraph 4 as
follows:</P>

<BLOCKQUOTE>

<P class="del">A #include directive shall identify a header or source
file that can be processed by the implementation.</P>

<P class="ins">
A <I>header search</I> for a sequence of characters searches a
sequence of places for a header identified
uniquely by that sequence of characters. How the places are determined
or the header identified is implementation-defined.</P>

<P class="ins">
A <I>source file search</I> for a sequence of characters attempts to
identify a source file that is named by the sequence of characters.
The named source file is searched for in an implementation-defined
manner. If the implementation does not support a source file search
for that sequence of characters, or if the search fails, the result of
the source file search is the result of a header search for the same
sequence of characters.</P>

<P>A preprocessing directive of the form
<PRE>
  # include <DEL>&lt; <I>h-char-sequence</I> &gt;</DEL> <INS><I>header-name</I></INS> <I>new-line</I>
</PRE>
<INS>causes the replacement of that directive by the entire contents
of the header or source file identified by <I>header-name</I>.</INS>
</P>

<P>
<INS>If the <I>header-name</I> is of the form</INS>
<PRE class="ins">
  &lt; <I>h-char-sequence</I> &gt;
</PRE>
<DEL>searches a sequence of implementation-defined places for a header
identified uniquely by the specified sequence between the &lt; and
&gt; delimiters, and causes the replacement of that directive by the
entire contents of the header. How the places are specified or the
header identified is implementation-defined</DEL> <INS>a header is
identified by a header search for the sequence of characters of
the <I>h-char-sequence</I></INS>.</P>

<P>
<DEL>A preprocessing directive</DEL>
<INS>If the <I>header-name</I> is</INS> of the form
<PRE>
  <DEL># include</DEL> " <I>q-char-sequence</I> " <DEL><I>new-line</I></DEL>
</PRE>
<DEL>causes the replacement of that directive by the entire contents
of the source file identified by the specified sequence between the "
delimiters. The named source file is searched for in an
implementation-defined manner. If this search is not supported, or if
the search fails, the directive is reprocessed as if it read</DEL>
<PRE class="del">
  # include &lt; <I>h-char-sequence</I> &gt; <I>new-line</I>
</PRE>
<DEL>with the identical contained sequence (including &gt; characters,
if any) from the original directive</DEL>
<INS>the source file or header is identified by a source file search
for the sequence of characters of the <I>q-char-sequence</I></INS>.
</P>

<P class="ins">
If a header search fails, or if a source file search or header search
identifies a header or source file that cannot be processed by the
implementation, the program is ill-formed.

[ Note: If the header or source file cannot be processed, the program
is ill-formed even when evaluating <TT>__has_include</TT>.  -- end
note ]</P>

<P>
A preprocessing directive of the form
<PRE>
  # include <I>pp-tokens</I> <I>new-line</I>
</PRE>
(that does not match <DEL>one of</DEL> the <DEL>two</DEL>
previous <DEL>forms</DEL> <INS>form</INS>) is permitted. The
preprocessing tokens after <TT>include</TT> in the directive are
processed just as in normal text (i.e., each identifier currently
defined as a macro name is replaced by its replacement list of
preprocessing tokens). <INS>Then, an attempt is made to form
a <I>header-name</I> preprocessing token (5.6 [<A href="https://wg21.link/lex.header">lex.header</A>])
from the whitespace and the characters of the spellings of the resulting sequence of
preprocessing tokens; the treatment of whitespace is
implementation-defined.</INS> If the <INS>attempt succeeds, the
directive with the so-formed <I>header-name</I> is processed as
specified for the previous form.  Otherwise</INS>
<DEL>directive resulting after all replacements does not match one of
the two previous forms</DEL>, the behavior is undefined.
</P>
<P>[<I>Note 1:</I> Adjacent <I>string-literal</I>s are not concatenated
into a single <I>string-literal</I> (see the translation phases in
5.2 [<A href="https://wg21.link/lex.phases">lex.phases</A>]); thus, an expansion that results in
two <I>string-literal</I>s is an invalid directive. &#8212;<I>end
note</I>]
</P>
<P class="del">The method by which a sequence of preprocessing tokens
between a &lt; and a &gt; preprocessing token pair or a pair of "
characters is combined into a single header name preprocessing token
is implementation-defined.</P>

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 15.4.1 [<A href="https://wg21.link/cpp.embed.gen#1">cpp.embed.gen</A>] paragraph 1 and paragraph 2 as follows:</P>

<BLOCKQUOTE>

<P class="ins">
A <I>bracket resource search</I> for a sequence of characters searches a
sequence of places for a resource identified
uniquely by that sequence of characters. How the places are determined
or the resource identified is implementation-defined.</P>

<P class="ins">
A <I>quote resource search</I> for a sequence of characters attempts
to identify a resource that is named by the sequence of
characters. The named resource is searched for in an
implementation-defined manner. If the implementation does not support
a quote resource search for that sequence of characters, or if the search
fails, the result of the quote resource search is the result of a
bracket resource search for the same sequence of characters.</P>

<P>
A preprocessing directive of the form
<PRE>
  # embed <DEL>&lt; <I>h-char-sequence</I> &gt;</DEL> <INS><I>header-name</I></INS> <I>pp-tokens</I><SUB>opt</SUB> <I>new-line</I>
</PRE>
<INS>causes the replacement of that directive by preprocessing tokens
derived from data in the resource identified by <I>header-name</I>, as
specified below.</INS>
</P>

<P>
<INS>If the <I>header-name</I> is of the form</INS>
<PRE class="ins">
  &lt; <I>h-char-sequence</I> &gt;
</PRE>
<DEL>searches a sequence of implementation-defined places for a
resource identified uniquely by the specified sequence between the
&lt; and &gt; delimiters. How the places are specified or the resource
identified is implementation-defined</DEL>
<INS>the resource is identified by a bracket resource search for the
sequence of characters of the <I>h-char-sequence</I></INS>.
</P>

<P>
<DEL>A preprocessing directive</DEL>
<INS>If the <I>header-name is</I></INS> of the form
<PRE>
  <DEL># embed</DEL> " <I>q-char-sequence</I> " <DEL><I>pp-tokens</I><SUB>opt</SUB> <I>new-line</I></DEL>
</PRE>
<DEL>searches for a resource identified by the specified sequence between
the " delimiters. The named resource is searched for in an
implementation-defined manner. If this search is not supported, or if
the search fails, the directive is reprocessed as if it read</DEL>
<PRE class="del">
  # embed &lt; <I>h-char-sequence</I> &gt; <I>pp-tokens</I><SUB>opt</SUB> <I>new-line</I>
</PRE>
<DEL>with the identical contained sequence (including &gt; characters,
if any) from the original directive</DEL>.
<INS>the resource is identified by a quote resource search for the
sequence of characters of the <I>q-char-sequence</I></INS>.
</P>

<P class="ins">
If a bracket resource search fails, or if a quote or bracket resource
search identifies a resource that cannot be processed by the
implementation, the program is ill-formed.

[ Note: If the resource cannot be processed, the program is ill-formed
even when processing <TT>#embed</TT> with <TT>limit(0)</TT>
(15.4.2.1 [<A href="https://wg21.link/cpp.embed.param.limit">cpp.embed.param.limit</A>]) or evaluating <TT>__has_embed</TT>.
-- end note ]
</P>

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 15.4.1 [<A href="https://wg21.link/cpp.embed.gen#10">cpp.embed.gen</A>] paragraph 10 and paragraph 11:</P>

<BLOCKQUOTE>

(10) A preprocessing directive of the form
<PRE>
  # embed <I>pp-tokens</I> <I>new-line</I>
</PRE>
(that does not match <DEL>one of</DEL> the
<DEL>two</DEL> previous <DEL>forms</DEL> <INS>form</INS>) is
permitted. The preprocessing tokens after <TT>embed</TT> in the
directive are processed just as in normal text (i.e., each identifier
currently defined as a macro name is replaced by its replacement list
of preprocessing tokens).
<DEL>The directive resulting after all replacements of the third form
shall match one of the two previous forms</DEL>
<INS>Then, an attempt is made to form a <I>header-name</I>
preprocessing token (5.6 [<A href="https://wg21.link/lex.header">lex.header</A>]) from the whitespace and the characters of
the spellings of the resulting sequence of preprocessing tokens
immediately after <TT>embed</TT>; the treatment of whitespace is
implementation-defined.  If the attempt succeeds, the directive with
the so-formed <I>header-name</I> is processed as specified for the
previous form.  Otherwise, the program is ill-formed</INS>.
<P>[<I>Note 1:</I> Adjacent <I>string-literal</I>s are not
concatenated into a single <I>string-literal</I> (see the translation
phases in (5.2 [<A href="https://wg21.link/lex.phases">lex.phases</A>])); thus, an expansion that results
in two <I>string-literal</I>s is an invalid directive. &#8212;<I>end
note</I>]</P> Any further processing as in normal text described for
the <DEL>two</DEL> previous <DEL>forms</DEL>
<INS>form</INS> is not performed.  [<I>Note 2:</I> That is, processing
as in normal text happens once and only once for the entire
directive. &#8212;<I>end note</I>]

<P>(11) [<I>Example 4:</I> If the directive matches
the <DEL>third</DEL> <INS>second</INS> form, the whole directive is
replaced. If the directive matches the first <DEL>two
forms</DEL> <INS>form</INS>, everything after the name is replaced.
<PRE class="del">
  #define prefix(ARG) suffix(ARG)
  #define THE_ADDITION "teehee"
  #define THE_RESOURCE ":3c"
  #embed ":3c"        prefix(THE_ADDITION)
  #embed THE_RESOURCE prefix(THE_ADDITION)
</PRE>
<PRE class="ins">
  #define EMPTY
  #define X myfile
  #define Y rsc
  #define Z 42
  #embed &lt;myfile.rsc&gt; prefix(Z)
  #embed EMPTY &lt;X.Y&gt;  prefix(Z)
</PRE>
is equivalent to:
<PRE class="del">
  #embed ":3c" suffix("teehee")
  #embed ":3c" suffix("teehee")
</PRE>
<PRE class="ins">
  #embed &lt;myfile.rsc&gt; prefix(42)
  #embed &lt;myfile.rsc&gt; prefix(42)
</PRE>
&#8212;<I>end example</I>]</P>

<P class="del">The method by which a sequence of preprocessing tokens
between a &lt; and a &gt; preprocessing token pair or a pair of "
characters is combined into a single resource name preprocessing token
is implementation-defined.</P>

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 15.7.3 [<A href="https://wg21.link/cpp.stringize#2">cpp.stringize</A>] paragraph 2 as follows:</P>



<BLOCKQUOTE>

... Otherwise, the original spelling of each preprocessing token in
the stringizing argument is retained in the character string literal,
except for special handling for producing the spelling
of <INS><I>header-name</I>s,</INS> <I>string-literal</I>s<INS>,</INS>
and <I>character-literal</I>s: a \ character is inserted before each "
and \ character of a <INS><I>header-name</I>,</INS>
<I>character-literal</I><INS>,</INS> or <I>string-literal</I>
(including the delimiting " characters). If the replacement that
results is not a valid character string literal, the behavior is
undefined. ...

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

<BR><BR><HR>
<A NAME="3016"></A><H4>3016.
  
Satisfying the syntactic requirements of <TT>#include</TT> and <TT>#embed</TT>
</H4>
<B>Section: </B>15.2&#160; [<A href="https://wg21.link/cpp.cond">cpp.cond</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Hubert Tong
 &#160;&#160;&#160;

 <B>Date: </B>2025-03-24


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

<P>Subclause 15.2 [<A href="https://wg21.link/cpp.cond#4">cpp.cond</A>] paragraph 4 talks about the
"syntactic requirements of a <TT>#include</TT> directive".  However,
those requirements are always satisfied, because the only requirement
is to have a sequence of preprocessing tokens according to the grammar
in 15.1 [<A href="https://wg21.link/cpp.pre">cpp.pre</A>].</P>

<P>However, a syntax check for properly forming a <I>header-name</I>
needs to be retained, because 15.3 [<A href="https://wg21.link/cpp.include#4">cpp.include</A>] paragraph 4
otherwise would yield undefined behavior.</P>

<P><B>Proposed resolution (approved by CWG 2025-06-20):</B></P>

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

<BLOCKQUOTE>

The header or source file identified by the parenthesized
preprocessing token sequence in each
contained <I>has-include-expression</I> is searched for as if that
preprocessing token sequence were the <I>pp-tokens</I> in a #include
directive, except that no further macro expansion is performed. If
<DEL>such a directive would not satisfy the syntactic requirements of
a #include directive</DEL>
<INS>the preprocessing token sequence does not consist solely of a
<I>header-name</I> or cannot be combined (15.3 [<A href="https://wg21.link/cpp.include">cpp.include</A>])
into a single <I>header-name</I> preprocessing token</INS>, the
program is ill-formed. The <I>has-include-expression</I> evaluates to
1 if the search for the source file succeeds, and to 0 if the search
fails.

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 15.2 [<A href="https://wg21.link/cpp.cond#5">cpp.cond</A>] paragraph 5 as follows:</P>

<BLOCKQUOTE>

The parenthesized <I>pp-balanced-token-seq</I> in each
contained <I>has-embed-expression</I> is processed as if
that <I>pp-balanced-token-seq</I> were the pp-tokens in the third form
of a #embed directive (15.4 [<A href="https://wg21.link/cpp.embed">cpp.embed</A>]). <DEL>If such a
directive would not satisfy the syntactic requirements of a #embed
directive, the program is ill-formed.</DEL>
The <I>has-embed-expression</I> evaluates to: ...

</BLOCKQUOTE>
</LI>
</OL>
<BR><BR><HR>
<A NAME="3018"></A><H4>3018.
  
Validity of <TT>defined</TT> in <TT>__has_embed</TT>
</H4>
<B>Section: </B>15.2&#160; [<A href="https://wg21.link/cpp.cond">cpp.cond</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Hubert Tong
 &#160;&#160;&#160;

 <B>Date: </B>2025-03-24


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

<P>Is the use of <TT>defined</TT> valid in <TT>__has_embed</TT>?  It
is not valid in cases where it would be interpreted by
the <TT>#if</TT> rules in <TT>#embed</TT>; see
15.4.2.1 [<A href="https://wg21.link/cpp.embed.param.limit#1">cpp.embed.param.limit</A>] paragraph 1.</P>

<P>To avoid confusion, <TT>defined</TT> should also be prohibited
inside <TT>__has_embed</TT>.</P>

<P><B>Proposed resolution (approved by CWG 2025-06-20):</B></P>

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


<BLOCKQUOTE>

The expression that controls conditional inclusion shall be an
integral constant expression except that identifiers (including those
lexically identical to keywords) are interpreted as described below123
and it may contain zero or more <I>defined-macro-expression</I>s,
<I>has-include-expression</I>s, <I>has-attribute-expression</I>s,
and/or <I>has-embed-expression</I>s as unary operator expressions.
<INS>A <I>defined-macro-expression</I> shall not appear within
a <I>has-include-expression</I> or <I>has-embed-expression</I>.</INS>

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 15.4.2.1 [<A href="https://wg21.link/cpp.embed.param.limit#1">cpp.embed.param.limit</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

<P>
An <I>embed-parameter</I> of the form
<TT>limit ( <I>pp-balanced-token-seq</I> )</TT> specifies the maximum
possible number of elements in the comma-delimited list. It shall
appear at most once in
the <I>embed-parameter-seq</I>. The <INS>preprocessing</INS>
token <TT>defined</TT> shall not appear in the
<DEL><I>constant-expression</I></DEL>
<INS><I>pp-balanced-token-seq</I></INS>.</P>

<P>
The <I>pp-balanced-token-seq</I> is evaluated as
a <I>constant-expression</I> using the rules as described in
conditional inclusion (15.2 [<A href="https://wg21.link/cpp.cond">cpp.cond</A>]), but without being
processed as in normal text an additional time.</P>

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

<BR><BR><HR>
<A NAME="3020"></A><H4>3020.
  
Missing specification for <TT>__has_cpp_attribute(indeterminate)</TT>
</H4>
<B>Section: </B>15.2&#160; [<A href="https://wg21.link/cpp.cond">cpp.cond</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Tim Song
 &#160;&#160;&#160;

 <B>Date: </B>2025-03-26


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

<P>P2795R5 (approved in March, 2024) should, but does not, update the
definition of <TT>__has_cpp_attribute</TT> for the new attribute it
added.</P>

<P><B>Proposed resolution (no objections during CWG reflector review starting 2025-03-31) (approved by CWG 2025-06-20):</B></P>

<P>Add a row to 15.2 [<A href="https://wg21.link/cpp.cond">cpp.cond</A>], table [tab:cpp.cond.ha], as follows:</P>

<BLOCKQUOTE>

<TABLE>
<TR>
<TH>Attribute</TH>
<TH>Value</TH>
</TR>
<TR class="ins">
<TD><TT>indeterminate</TT></TD>
<TD>202403L</TD>
</TR>
</TABLE>

</BLOCKQUOTE>

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