<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=us-ascii">
<TITLE>
    Core NB Comment Resolutions
   </TITLE>
</HEAD>
<BODY>
<TABLE ALIGN="RIGHT" CELLSPACING="0" CELLPADDING="0">
<TR>
<TD ALIGN="RIGHT">
      Document number:
     </TD>
<TD>
       &#160;P1971R0</TD>
</TR>
<TR>
<TD ALIGN="RIGHT">
      Date:
     </TD>
<TD>
      &#160;2019-11-08</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:2017
     </TD>
</TR>
<TR>
<TD ALIGN="RIGHT">
      Reply to:
     </TD>
<TD>
      &#160;William M. Miller
     </TD>
</TR>
<TR>
<TD></TD>
<TD>
      &#160;Edison Design Group, Inc.
     </TD>
</TR>
<TR>
<TD></TD>
<TD>
      &#160;<A HREF="mailto://wmm@edg.com">wmm@edg.com</A></TD>
</TR>
</TABLE><BR CLEAR="ALL"><BR><CENTER>
<H2>
     Core Language Changes for NB Comments
     at the
     November, 2019 (Belfast) 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/2019/n4835.pdf">WG21 N4835</A>.
   </P>
<HR><A NAME="RU007"></A><H4>RU007.
  
[basic.life].8.3 Relax pointer value/aliasing rules
</H4>


<P>(This also addresses US047.)</P>

<OL><LI><P>Delete the note and example from
6.7.2 [intro.object]:</P></LI>

<BLOCKQUOTE>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">[<I>Note:</I> If the subobject contains a reference member
or a <TT>const</TT> subobject, the name of the original
subobject cannot be used to access the new object
(6.7.3 [basic.life]). &#8212;<I>end note</I>]
[<I>Example:</I></SPAN></P>

<PRE>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">  struct X { const int n; };
  union U { X x; float f; };
  void tong() {
    U u = {{ 1 }};
    u.f = 5.f;                          //<SPAN style="font-family:Times;font-style:italic"> OK, creates new subobject of </SPAN>u<SPAN style="font-family:Times;font-style:italic"> (11.5 [class.union])</SPAN>
    X *p = new (&amp;u.x) X {2};            //<SPAN style="font-family:Times;font-style:italic"> OK, creates new subobject of </SPAN>u
    assert(p-&gt;n == 2);                  //<SPAN style="font-family:Times;font-style:italic"> OK</SPAN>
    assert(*std::launder(&amp;u.x.n) == 2); //<SPAN style="font-family:Times;font-style:italic"> OK</SPAN>
    assert(u.x.n == 2);                 //<SPAN style="font-family:Times;font-style:italic"> undefined behavior, </SPAN>u.x<SPAN style="font-family:Times;font-style:italic"> does not name new subobject</SPAN>
  }</SPAN>
</PRE>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">&#8212;<I>end example</I>]</SPAN></P>

</BLOCKQUOTE>

<LI><P>Change 6.7.3 [basic.life] bullet 8.3 as follows:</P></LI>

<BLOCKQUOTE>

<P>If, after the lifetime of an object has ended and before the
storage which the object occupied is reused or released, a
new object is created at the storage location which the
original object occupied, a pointer that pointed to the
original object, a reference that referred to the original
object, or the name of the original object will
automatically refer to the new object and, once the lifetime
of the new object has started, can be used to manipulate the
new object, if:</P>

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

<LI><P>the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">type of the</SPAN> original object
is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">not const-qualified, and, if a class type, does not
contain any non-static data member whose type is
const-qualified or a reference type</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">neither a
complete object that is const-qualified nor a subobject of
such an object</SPAN>, and</P></LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="US019, US020"></A><H4>US019, US020.
  
Update ISO 9899 document reference from C11 to C17
</H4>


<OL><LI><P>Change 1 [intro.scope] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

C ++ is a general purpose programming language based on the
C programming language as described in ISO/IEC <SPAN style="text-decoration:line-through;background-color:#FFA0A0">9899:2011</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">9899:2018</SPAN> Programming languages &#8211; C
(hereinafter referred to as the C standard). C++ provides...

</BLOCKQUOTE>

<LI><P>Change 2 [intro.refs] bullet 1.5 as follows:</P></LI>

<BLOCKQUOTE>

<P>The following documents are referred to in the text in such
a way that some or all of their content constitutes
requirements of this document. For dated references, only
the edition cited applies. For undated references, the
latest edition of the referenced document (including any
amendments) applies.</P>

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

<LI><P>ISO/IEC <SPAN style="text-decoration:line-through;background-color:#FFA0A0">9899:2011</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">9899:2018</SPAN>, Programming languages &#8211; C</P></LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

<LI><P>Change 2 [intro.refs] paragraph 2 as follows:</P>

<BLOCKQUOTE>

The library described in Clause 7 of ISO/IEC <SPAN style="text-decoration:line-through;background-color:#FFA0A0">9899:2011</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">9899:2018</SPAN> is hereinafter called the C standard
library.<SUP>1</SUP>

</BLOCKQUOTE>
</LI>

</OL>

<BR><BR><HR><A NAME="CA038"></A><H4>CA038.
  
Consider trailing <I>requires-clause</I>s for function identity
</H4>


<OL><LI><P>Merge 6.6 [basic.link] bullets 11.3 and
11.4 with the following changes:</P></LI>

<BLOCKQUOTE>

<P>Two names that are the same (Clause 6 [basic])
and that are declared in different scopes shall denote the
same variable, function, type, template or namespace if</P>

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

<LI><P>when both names denote functions <SPAN style="font-weight:bold;background-color:#A0FFA0">or function
templates</SPAN>, the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">parameter-type-lists
of the functions (9.3.3.5 [dcl.fct]) are
identical; and</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">signatures
(3.19 [defns.signature], 3.20 [defns.signature.templ])
are the same.</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">when both names denote function templates, the
signatures (13.7.6.1 [temp.over.link]) are the
same.</SPAN></P></LI>

</UL>

</BLOCKQUOTE>

<LI><P>Change 9.9 [namespace.udecl] paragraph 14 as follows:</P></LI>

<BLOCKQUOTE>

If a function declaration in namespace scope or block scope
has the same name and the same parameter-type-list
(9.3.3.5 [dcl.fct]) as a function introduced by
a <I>using-declaration</I>, and the declarations do not
declare the same function, the program is ill-formed. If a
function template declaration in namespace scope has the
same name, parameter-type-list, <SPAN style="font-weight:bold;background-color:#A0FFA0">trailing
<I>requires-clause</I> (if any),</SPAN> return type, and
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">template parameter
list</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>template-head</I></SPAN> as a function
template introduced by a <I>using-declaration</I>, the
program is ill-formed. [<I>Note:</I>
Two <I>using-declaration</I>s...

</BLOCKQUOTE>

<LI><P>Change 9.9 [namespace.udecl] paragraph 14 as follows:</P></LI>

<BLOCKQUOTE>

When a <I>using-declarator</I> brings declarations from a
base class into a derived class, member functions and member
function templates in the derived class override and/or hide
member functions and member function templates with the same
name, parameter-type-list (9.3.3.5 [dcl.fct]),
<SPAN style="font-weight:bold;background-color:#A0FFA0">trailing <I>requires-clause</I> (if any),</SPAN>
cv-qualification, and <I>ref-qualifier</I> (if any) in a
base class (rather than conflicting). Such hidden or
overridden declarations are excluded from the set of
declarations introduced by
the <I>using-declarator</I>. [<I>Example:</I>...

</BLOCKQUOTE>

<LI><P>No change to 9.11 [dcl.link] paragraph 5:</P></LI>

<BLOCKQUOTE>

If two declarations declare functions with the same name and
parameter-type-list (9.3.3.5 [dcl.fct]) to be
members of the same namespace or declare objects with the
same name to be members of the same namespace and the
declarations give the names different language linkages, the
program is ill-formed; no diagnostic is required if the
declarations appear in different translation units. Except...

</BLOCKQUOTE>

<LI><P>Change 12.2 [over.load] bullets 2.2 and 2.3
as follows:</P></LI>

<BLOCKQUOTE>

<P>Certain function declarations cannot be overloaded:</P>

<UL><LI><P>Function declarations that differ only in the return type,
the exception specification (14.5 [except.spec]), or
both cannot be overloaded.</P></LI>

<LI><P>Member function declarations with the same name<SPAN style="font-weight:bold;background-color:#A0FFA0">,</SPAN>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">and</SPAN> the same parameter-type-list
(9.3.3.5 [dcl.fct])<SPAN style="font-weight:bold;background-color:#A0FFA0">, and the same
trailing <I>requires-clause</I> (if any)</SPAN> cannot be
overloaded if any of them is a static member function
declaration (11.4.8 [class.static]). Likewise, member
function template declarations with the same name, the same
parameter-type-list, <SPAN style="font-weight:bold;background-color:#A0FFA0">the same trailing
<I>requires-clause</I> (if any),</SPAN> and the
same <SPAN style="text-decoration:line-through;background-color:#FFA0A0">template parameter
lists</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>template-head</I></SPAN> cannot be
overloaded if any of them is a static member function
template declaration.  The types of the implicit object
parameters constructed for the member functions for the
purpose of overload resolution (12.4.1 [over.match.funcs])
are not considered when comparing parameter-type-lists for
enforcement of this rule. In contrast, if there is no static
member function declaration among a set of member function
declarations with the same name<SPAN style="font-weight:bold;background-color:#A0FFA0">,</SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">and</SPAN>
the same parameter-type-list, <SPAN style="font-weight:bold;background-color:#A0FFA0">and the same trailing
<I>requires-clause</I> (if any),</SPAN> then these member
function declarations can be overloaded if they differ in
the type of their implicit object
parameter. [<I>Example:</I>...</P></LI>

<LI><P>Member function declarations with the same name<SPAN style="font-weight:bold;background-color:#A0FFA0">,</SPAN>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">and</SPAN> the same parameter-type-list
(9.3.3.5 [dcl.fct])<SPAN style="font-weight:bold;background-color:#A0FFA0">, and the same
trailing <I>requires-clause</I> (if any),</SPAN> as well as
member function template declarations with the same name,
the same parameter-type-list, <SPAN style="font-weight:bold;background-color:#A0FFA0">the same trailing
<I>requires-clause</I> (if any),</SPAN> and the
same <SPAN style="text-decoration:line-through;background-color:#FFA0A0">template parameter
lists</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>template-head</I>,</SPAN> cannot be
overloaded if any of them, but not all, have
a <I>ref-qualifier</I> (9.3.3.5 [dcl.fct]).
[<I>Example:</I>...</P></LI>

</UL>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="CZ044"></A><H4>CZ044.
  
Allow constexpr <TT>construct_at</TT>/<TT>destroy_at</TT> for automatic storage duration
</H4>


<P>Change 7.7 [expr.const] paragraph 5 as follows:</P>

<BLOCKQUOTE>

<P>For the purposes of determining whether an
expression <SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>e</TT></SPAN> is a core constant
expression, the evaluation of a call to a member function of
<TT>std::allocator&lt;T&gt;</TT>
as defined in
20.10.10.1 [allocator.members], where <TT>T</TT>
is a literal type,
does not disqualify the expression from being a core
constant expression, even if the actual evaluation of such a
call would otherwise fail the requirements for a core
constant expression. Similarly, the evaluation of a call to
<TT>std::destroy_at</TT>, <TT>std::ranges::destroy_at</TT>,
<TT>std::construct_at</TT>,
or <TT>std::ranges::construct_at</TT> is a valid core
constant expression unless:</P>

<UL><LI><P>for a call to <TT>std::construct_at</TT>
or <TT>std::ranges::construct_at</TT>, the first argument,
of type <TT>T*</TT>, does not point to storage allocated
with <TT>std::allocator&lt;T&gt;</TT> <SPAN style="font-weight:bold;background-color:#A0FFA0">or to an
object whose lifetime began within the evaluation of
<TT>e</TT>,</SPAN> or the evaluation of the underlying
constructor call is not a core constant expression,
or</P></LI>

<LI><P>for a call to <TT>std::destroy_at</TT>
or <TT>std::ranges::destroy_at</TT>, the first argument, of
type <TT>T*</TT>, does not point to storage allocated
with <TT>std::allocator&lt;T&gt;</TT> <SPAN style="font-weight:bold;background-color:#A0FFA0">or to an
object whose lifetime began within the evaluation of
<TT>e</TT>,</SPAN> or the evaluation of
the underlying destructor call is not a core constant
expression.</P></LI>

</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="US052"></A><H4>US052.
  
Non-executed <TT>return</TT> statements in coroutines
</H4>


<P>Change 8.7.4 [stmt.return.coroutine] paragraph 1 as follows:</P>

<BLOCKQUOTE>

A coroutine returns to its caller or resumer
(9.5.4 [dcl.fct.def.coroutine]) by the <TT>co_return</TT>
statement or when suspended (7.6.2.3 [expr.await]).
A coroutine shall not <SPAN style="text-decoration:line-through;background-color:#FFA0A0">return to its caller or resumer by</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">contain</SPAN> a
<TT>return</TT> statement (8.7.3 [stmt.return]).
<SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> For this determination, it is irrelevant
whether the <TT>return</TT> statement is enclosed by a discarded
statement (8.5.1 [stmt.if]). &#8212;<I>end note</I>]</SPAN>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="US053"></A><H4>US053.
  
Mandate the return type for <TT>return_void</TT> and <TT>return_value</TT> to be <TT>void</TT>
</H4>


<P>Change 8.7.4 [stmt.return.coroutine] paragraph 2 as follows:</P>

<BLOCKQUOTE>

<P>The <I>expr-or-braced-init-list</I> of a <TT>co_return</TT>
statement is called its operand. Let <I>p</I> be an lvalue
naming the coroutine promise object
(9.5.4 [dcl.fct.def.coroutine]). A <TT>co_return</TT> statement
is equivalent to:</P>

<UL><TT>{</TT> <I>S</I><TT>; goto <I>final-suspend</I>; }</TT>
</UL>

<P>where <TT><I>final-suspend</I></TT> is the
exposition-only label defined in 9.5.4 [dcl.fct.def.coroutine]
and <I>S</I> is defined as follows:</P>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">If the operand is a <I>braced-init-list</I> or an
expression of non-<TT>void</TT> type,</SPAN> <I>S</I>
is <I>p</I><TT>.return_value(</TT><I>expr-or-braced-init-list</I><TT>)</TT><SPAN style="text-decoration:line-through;background-color:#FFA0A0">,
if the operand is a <I>braced-init-list</I> or an expression
of non-<TT>void</TT> type;</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">. The expression
<I>S</I> shall be a prvalue of type <TT>void</TT>.</SPAN>
</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">Otherwise,</SPAN> <I>S</I>
is <SPAN style="font-weight:bold;background-color:#A0FFA0">the <I>compound-statement</I></SPAN>
<TT>{</TT> <I>expression<SUB>opt</SUB></I>
<TT>;</TT>
<I>p</I><TT>.return_void(); }</TT><SPAN style="text-decoration:line-through;background-color:#FFA0A0">, otherwise;</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">.
The expression <I>p</I><TT>.return_void()</TT> shall be a
prvalue of type <TT>void</TT>.</SPAN></P></LI>

</UL>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>S</I> shall be a prvalue of type <TT>void</TT>.</SPAN></P>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="US065"></A><H4>US065.
  
Apply Coroutines TS issue 24 from P0664R8
</H4>


<P>Change 9.5.4 [dcl.fct.def.coroutine] paragraph 5 as follows:</P>

<BLOCKQUOTE>

<P>A coroutine behaves as if its <I>function-body</I> were
replaced by:</P>

<UL><TT>{</TT>
<UL><I>promise_type</I> <TT><I>promise</I></TT> <I>promise-constructor-arguments</I> <TT>;</TT><BR>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>try {</TT></SPAN>
<UL><TT>co_await <I>promise</I>.initial_suspend() ;</TT></UL>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0"><TT>try {</TT></SPAN><BR>
<UL><I>function-body</I></UL>
<TT>} catch ( ... ) {</TT><BR>
<UL><SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>if (!</TT><I>initial-await-resume-called</I><TT>)</TT></SPAN>
<UL><SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>throw ;</TT></SPAN></UL>
</UL>
<UL><TT><I>promise</I>.unhandled_exception() ;</TT></UL>
<TT>}</TT></UL>
<TT><I>final-suspend</I> :</TT>
<UL><TT>co_await <I>promise</I>.final_suspend() ;</TT></UL>
<TT>}</TT>
</UL>

<P>where</P>

<UL><LI><P>the <I>await-expression</I> containing the call to
<TT>initial_suspend</TT> is the initial suspend point,
and</P></LI>

<LI><P>the <I>await-expression</I> containing the call to
<TT>final_suspend</TT> is the final suspend point,
and</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0"><I>initial-await-resume-called</I> is initially
<TT>false</TT> and is set to <TT>true</TT> immediately before the
evaluation of <I>await-resume</I> (7.6.2.3 [expr.await])
of the initial suspend point, and</SPAN></P></LI>

<LI><P><I>promise-type</I> denotes the promise type, and</P></LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="GB079"></A><H4>GB079.
  
Add example for <I>private-module-fragment</I>
</H4>


<OL><LI><P>Delete the following production from the grammar in
6.6 [basic.link] paragraph 1:</P></LI>

<UL><SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>private-module-fragment:</I></SPAN>
<UL><SPAN style="text-decoration:line-through;background-color:#FFA0A0"><TT>module : private ;</TT> <I>top-level-declaration-seq<SUB>opt</SUB></I>
</SPAN>
</UL>
</UL>

<LI><P>Delete 6.6 [basic.link] paragraph 2:</P></LI>

<BLOCKQUOTE>

<SPAN style="text-decoration:line-through;background-color:#FFA0A0">A <I>private-module-fragment</I> shall appear only in a
primary module interface unit (10.1 [module.unit]). A
module unit with a <I>private-module-fragment</I> shall be
the only module unit of its module; no diagnostic is
required.</SPAN>

</BLOCKQUOTE>

<LI><P>Add the following as a new section following
10.4 [module.global]:</P></LI>

<BLOCKQUOTE>

<P><B><SPAN style="font-weight:bold;background-color:#A0FFA0">Private Module Fragment [module.private.frag]</SPAN></B></P>

<UL><SPAN style="font-weight:bold;background-color:#A0FFA0"><I>private-module-fragment:</I></SPAN>
<UL><SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>module : private ;</TT> <I>top-level-declaration-seq<SUB>opt</SUB></I></SPAN>
</UL>
</UL>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">A <I>private-module-fragment</I> shall appear only in a
primary module interface unit (10.1 [module.unit]). A
module unit with a <I>private-module-fragment</I> shall be the
only module unit of its module; no diagnostic is required.</SPAN></P>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> A <I>private-module-fragment</I> ends the
primary module interface and commences an unimported implementation
partition of the module. A <I>private-module-fragment</I> allows
a module to consist of a primary interface and a single
implementation partition without needing multiple translation
units. The presence of a <I>private-module-fragment</I> affects:</SPAN></P>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">the point by which the definition of an inline
function declared in the module interface unit purview is
required (9.2.7 [dcl.inline]),</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">the point by which the definition of a function with
a placeholder return type declared in the module interface unit
purview is required (9.2.8.5 [dcl.spec.auto]),</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">the instantiation contexts of templates instantiated
before it (10.5 [module.context]), and</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">the reachability of entities declared in the
primary interface unit (10.6 [module.reach]).</SPAN></P></LI>

</UL>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end note</I>]</SPAN></P>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Example:</I></SPAN></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  export module A;
  inline void h();     //<SPAN style="font-family:Times;font-style:italic"> error: inline function </SPAN>h<SPAN style="font-family:Times;font-style:italic"> not defined</SPAN>
                       //<SPAN style="font-family:Times;font-style:italic"> before private module fragment</SPAN>
  static void fn();
  export struct X;
  export void g(X *x) {
   fn();               //<SPAN style="font-family:Times;font-style:italic"> OK: call to static function in same TU</SPAN>
  }
  export X *factory(); //<SPAN style="font-family:Times;font-style:italic"> OK</SPAN>

  module :private;
  struct X {};         //<SPAN style="font-family:Times;font-style:italic"> definition not reachable from importers of </SPAN>A
  X *factory() {
    return new X ();
  }
  void h() {}
  void fn() {}</SPAN>
</PRE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end example</I>]</SPAN></P>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="US087"></A><H4>US087.
  
Header unit imports cannot be cyclic, either
</H4>


<P>Change 10.4 [module.global] paragraph 9 as follows:</P>

<BLOCKQUOTE>

A translation unit has an <I>interface dependency</I> on a
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">module</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">translation</SPAN> unit <TT>U</TT> if
it contains a <I>module-declaration</I>
or <I>module-import-declaration</I> that imports <TT>U</TT>
or if it has an interface dependency on a <SPAN style="text-decoration:line-through;background-color:#FFA0A0">module</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">translation</SPAN> unit that has an interface dependency
on <TT>U</TT>. A translation unit shall not have an
interface dependency on itself. [<I>Example:</I>...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="US111"></A><H4>US111.
  
Constraint normalization and negation
</H4>


<P>Add the following as a new paragraph at the end of
13.5.1.1 [temp.constr.op] following paragraph 4:</P>

<BLOCKQUOTE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> A logical negation expression
(7.6.2.1 [expr.unary.op]) is an atomic constraint; the
negation operator is not treated as a logical operation on
constraints. As a result, distinct negation
<I>constraint-expression</I>s that are equivalent under
13.7.6.1 [temp.over.link] do not subsume one another under
13.5.4 [temp.constr.order]. Furthermore, if substitution to
determine whether an atomic constraint is satisfied
(13.5.1.2 [temp.constr.atomic]) encounters a substitution failure,
the constraint is not satisfied, regardless of the presence of a
negation operator. It is unclear in principle what the desired
value is of a substitution failure in a negated concept-id; in the
example below, does <TT>requires !sad&lt;typename T::type&gt;</TT>
mean to require that there be no sad nested type, or that there be
a nested type that is not sad? In effect it means the latter, whereas
<TT>requires !sad_nested_type&lt;T&gt;</TT> means the former.</SPAN></P>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Example:</I></SPAN></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">   template &lt;class T&gt; concept sad = false;

   template &lt;class T&gt; int f1(T) requires (!sad&lt;T&gt;);
   template &lt;class T&gt; int f1(T) requires (!sad&lt;T&gt;) &amp;&amp; true;
   int i1 = f1(42);    //<SPAN style="font-family:Times;font-style:italic"> ambiguous, </SPAN>!sad&lt;T&gt;<SPAN style="font-family:Times;font-style:italic"> constraints are not formed from the same expression</SPAN>

   template &lt;class T&gt; concept not_sad = !sad&lt;T&gt;;
   template &lt;class T&gt; int f2(T) requires not_sad&lt;T&gt;;
   template &lt;class T&gt; int f2(T) requires not_sad&lt;T&gt; &amp;&amp; true;
   int i2 = f2(42);    //<SPAN style="font-family:Times;font-style:italic"> OK, </SPAN>!sad&lt;T&gt;<SPAN style="font-family:Times;font-style:italic"> constraints both come from </SPAN>not_sad

   template &lt;class T&gt; int f3(T) requires (!sad&lt;typename T::type&gt;);
   int i3 = f3(42);    //<SPAN style="font-family:Times;font-style:italic"> error, constraint not satisfied due to substitution failure </SPAN>

   template &lt;class T&gt; concept sad_nested_type = sad&lt;typename T::type&gt;;
   template &lt;class T&gt; int f4(T) requires (!sad_nested_type&lt;T&gt;);
   int i4 = f4(42);    //<SPAN style="font-family:Times;font-style:italic"> OK, substitution failure contained within </SPAN>sad_nested_type</SPAN>
</PRE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end example</I>] &#8212;<I>end note</I>]</SPAN></P>

</BLOCKQUOTE>

<I>[Drafting note: use of the term &#8220;concept-id&#8221;
in this wording assumes the definition in the change to
13.3 [temp.names] for CA096.]</I>

<BR><BR><HR><A NAME="US132"></A><H4>US132.
  
Macros from the command-line not exported by header units
</H4>


<P>Change 15.4 [cpp.import] paragraph 3 as follows:</P>

<BLOCKQUOTE>

Each <TT>#define</TT> directive encountered when
preprocessing each translation unit in a program results in
a distinct <I>macro definition</I>. <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> A
predefined macro name (15.11 [cpp.predefined]) is not
introduced by a <TT>#define</TT> directive. Implementations
providing mechanisms to predefine additional macros are
encouraged not to treat them as being introduced by a
<TT>#define</TT> directive. &#8212;<I>end note</I>]</SPAN>
Importing macros from a header unit...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="US367"></A><H4>US367.
  
Instead of header inclusion, also permit header unit import
</H4>


<OL><LI><P>Change 6.7.5.4 [basic.stc.dynamic] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

...These implicit declarations introduce only the function
names <TT>operator new</TT>, <TT>operator
new[]</TT>, <TT>operator delete</TT>, and <TT>operator
delete[]</TT>. [<I>Note:</I> The implicit declarations do
not introduce the names <TT>std,
std::size_t</TT>, <TT>std::align_val_t</TT>, or any other
names that the library uses to declare these names. Thus,
a <I>new-expression</I>, <I>delete-expression</I><SPAN style="font-weight:bold;background-color:#A0FFA0">,</SPAN>
or function call that refers to one of these functions
without <SPAN style="font-weight:bold;background-color:#A0FFA0">importing or</SPAN> including the header
<TT>&lt;new&gt;</TT> (17.6.1 [new.syn]) is
well-formed. However, referring to <TT>std</TT>
or <TT>std::size_t</TT> or <TT>std::align_val_t</TT> is
ill-formed unless the name has been declared
by <SPAN style="font-weight:bold;background-color:#A0FFA0">importing or</SPAN> including the appropriate
header. &#8212;<I>end note</I>] Allocation and/or
deallocation functions may also be declared and defined for
any class (11.12 [class.free]).

</BLOCKQUOTE>

<LI><P>Change 7.6.1.7 [expr.typeid] paragraph 6 as follows:</P></LI>

<BLOCKQUOTE>

If the header <TT>&lt;typeinfo&gt; </TT>
(17.7.2 [type.info]) is not <SPAN style="font-weight:bold;background-color:#A0FFA0">imported or</SPAN>
included prior to a use of <TT>typeid</TT>, the program is
ill-formed.

</BLOCKQUOTE>

<LI><P>Change 7.6.8 [expr.spaceship] paragraph 10 as follows:</P></LI>

<BLOCKQUOTE>

The five comparison category types
(17.11.2 [cmp.categories]) (the types
<TT>std::strong_ordering</TT>, <TT>std::strong_equality</TT>,
<TT>std::weak_ordering</TT>, <TT>std::weak_equality</TT>, and
<TT>std::partial_ordering</TT>) are not predefined; if the header
<TT>&lt;compare&gt;</TT> (17.11.1 [compare.syn]) is
not <SPAN style="font-weight:bold;background-color:#A0FFA0">imported or</SPAN> included prior to a use of such a
class type &#8211; even an implicit use in which the type is
not named (e.g., via the <TT>auto</TT> specifier
(9.2.8.5 [dcl.spec.auto]) in a defaulted three-way
comparison (11.11.3 [class.spaceship]) or use of the
built-in operator) &#8211; the program is ill-formed.

</BLOCKQUOTE>

<LI><P>Change 9.4.4 [dcl.init.list] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

...The template <TT>std::initializer_list</TT> is not
predefined; if the header <TT>&lt;initializer_list&gt;</TT>
is not <SPAN style="font-weight:bold;background-color:#A0FFA0">imported or</SPAN> included prior to a use
of <TT>std::initializer_list</TT> &#8211; even an implicit
use in which the type is not named
(9.2.8.5 [dcl.spec.auto]) &#8211; the program is
ill-formed.

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="CA378"></A><H4>CA378.
  
Remove constrained non-template functions
</H4>


<P>(This also addresses US095, US109, and CA110.)</P>

<OL><LI><P>Change 7.5.4 [expr.prim.id] paragraph 5 as follows:</P></LI>

<BLOCKQUOTE>

A program that refers explicitly or implicitly to a function
with a trailing <I>requires-clause</I>
whose <I>constraint-expression</I> is not satisfied, other
than to declare it, is ill-formed. [<I>Example:</I>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  template&lt;typename T&gt; struct A {</SPAN>
    <SPAN style="font-weight:bold;background-color:#A0FFA0">static</SPAN> void f(int) requires false;
<SPAN style="font-weight:bold;background-color:#A0FFA0">  }</SPAN>

  void g() {
    <SPAN style="font-weight:bold;background-color:#A0FFA0">A&lt;int&gt;::</SPAN>f(0);                      //<SPAN style="font-family:Times;font-style:italic"> error: cannot call </SPAN>f
    void (*p1)(int) = <SPAN style="font-weight:bold;background-color:#A0FFA0">A&lt;int&gt;::</SPAN>f;       //<SPAN style="font-family:Times;font-style:italic"> error: cannot take the address of </SPAN>f
    decltype(<SPAN style="font-weight:bold;background-color:#A0FFA0">A&lt;int&gt;::</SPAN>f)* p2 = nullptr; //<SPAN style="font-family:Times;font-style:italic"> error: the type </SPAN>decltype(<SPAN style="font-weight:bold;background-color:#A0FFA0">A&lt;int&gt;::</SPAN>f)<SPAN style="font-family:Times;font-style:italic"> is invalid</SPAN>
  }
</PRE>

</BLOCKQUOTE>

<LI><P>Change 9.3 [dcl.decl] paragraph 4 as follows:</P></LI>

<BLOCKQUOTE>

<P>The optional <I>requires-clause</I> (Clause
13 [temp]) in an <I>init-declarator</I>
or <I>member-declarator</I> shall not be present when the
declarator does not declare a <SPAN style="font-weight:bold;background-color:#A0FFA0">templated</SPAN> function
(9.3.3.5 [dcl.fct]). When present after a
declarator, the <I>requires-clause</I> is called the
trailing <I>requires-clause</I>. The
trailing <I>requires-clause</I> introduces
the <I>constraint-expression</I> that results from
interpreting its <I>constraint-logical-or-expression</I> as
a <I>constraint-expression</I>. [<I>Example:</I></P>

<PRE>
  void f1(int a) requires true;                //<SPAN style="font-family:Times;font-style:italic"> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">OK</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">error: non-templated function</SPAN></SPAN>
  <SPAN style="font-weight:bold;background-color:#A0FFA0">template&lt;typename T&gt;</SPAN>
    auto f2(<SPAN style="text-decoration:line-through;background-color:#FFA0A0">int</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">T</SPAN> a) -&gt; bool requires true;    //<SPAN style="font-family:Times;font-style:italic"> OK</SPAN>
  <SPAN style="font-weight:bold;background-color:#A0FFA0">template&lt;typename T&gt;</SPAN>
    auto f3(<SPAN style="text-decoration:line-through;background-color:#FFA0A0">int</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">T</SPAN> a) requires true -&gt; bool;    //<SPAN style="font-family:Times;font-style:italic"> error: requires-clause precedes trailing-return-type</SPAN>
  void (*pf)() requires true;                  //<SPAN style="font-family:Times;font-style:italic"> error: constraint on a variable</SPAN>
  void g(int (*)() requires true);             //<SPAN style="font-family:Times;font-style:italic"> error: constraint on a parameter-declaration</SPAN>

  auto* p = new void(*)(char) requires true;   //<SPAN style="font-family:Times;font-style:italic"> error: not a function declaration</SPAN>
</PRE>

</BLOCKQUOTE>

<LI><P>Change 13.5.2 [temp.constr.decl] paragraphs 1 and 3 as
follows:</P></LI>

<BLOCKQUOTE>

<P>A template declaration (Clause 13 [temp]) or
<SPAN style="font-weight:bold;background-color:#A0FFA0">templated</SPAN> function declaration
(9.3.3.5 [dcl.fct]) can be constrained by the use
of a <I>requires-clause</I>. This allows...</P>

<P>Constraints can also be associated...</P>

<P>A <SPAN style="text-decoration:line-through;background-color:#FFA0A0">template's</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">declaration's</SPAN>
associated constraints are defined as follows:...</P>

</BLOCKQUOTE>

</OL>

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