<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=us-ascii">
<TITLE>
    Core "ready" Issues
   </TITLE>
</HEAD>
<BODY>
<TABLE ALIGN="RIGHT" CELLSPACING="0" CELLPADDING="0">
<TR>
<TD ALIGN="RIGHT">
      Document number:
     </TD>
<TD>
       &#160;P0167R2</TD>
</TR>
<TR>
<TD ALIGN="RIGHT">
      Date:
     </TD>
<TD>
      &#160;2016-03-04</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:2014
     </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>
<TR>
<TD ALIGN="RIGHT">
      Audience:
     </TD>
<TD>
      &#160;WG21
     </TD>
</TR>
</TABLE><BR CLEAR="ALL"><BR><CENTER>
<H2>
     Core Language Working Group "ready" Issues
     for the
     February, 2016 (Jacksonville) meeting
    </H2>
</CENTER><BR><P>
    Section references in this document reflect the section numbering
    of document
    <A HREF="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4567.pdf">WG21 N4567</A>.
   </P>
<HR><A NAME="1734"></A><H4>1734.
  
Nontrivial deleted copy functions
</H4><B>Section: </B>12.8&#160; [class.copy]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>James Widman
 &#160;&#160;&#160;

 <B>Date: </B>2013-08-09




<P>The intent was for PODs in C++11 to be a superset of C++03 PODs.
Consequently, in the following example, <TT>C</TT> should be a POD
but isn't:</P>

<PRE>
  struct A {
    const int m;
    A&amp; operator=(A const&amp;) = default; //<SPAN style="font-family:Times;font-style:italic"> deleted and trivial, so </SPAN>A<SPAN style="font-family:Times;font-style:italic"> is a</SPAN>
                                      //<SPAN style="font-family:Times;font-style:italic"> POD, as it would be in 2003</SPAN>
                                      //<SPAN style="font-family:Times;font-style:italic"> without this explicit </SPAN>op=<SPAN style="font-family:Times;font-style:italic"> decl</SPAN>
  };
  static_assert(__is_trivially_copyable(A), "");

  struct B { 
    int i; 
    B&amp; operator=(B &amp;) &amp; = default;      //<SPAN style="font-family:Times;font-style:italic"> non-trivial</SPAN>
    B&amp; operator=(B const&amp;) &amp; = default; //<SPAN style="font-family:Times;font-style:italic"> trivial</SPAN>
  };

  struct C {
    const B m;
    C&amp; operator=(C const&amp; r) = default; //<SPAN style="font-family:Times;font-style:italic"> deleted (apparently), but non-trivial (apparently)</SPAN>
    /*<SPAN style="font-family:Times;font-style:italic"> Notionally:</SPAN>
      C&amp; operator=(C const&amp; r) {
        (*this).m.operator=(r.m);
        return *this;
      }
    */
  };
  static_assert(!__is_trivially_copyable(C), "");  
</PRE>

<P>This is because of the following text from 12.8 [class.copy]
paragraph 25:</P>

<BLOCKQUOTE>

for each non-static data member of <TT>X</TT> that is of class type (or
array thereof), the assignment operator selected to copy/move that member
is trivial;

</BLOCKQUOTE>

<P>In this case, overload resolution fails, so no assignment operator
is selected, so <TT>C::operator=(const C&amp;)</TT> is non-trivial.</P>

<P>(See also issue 1928.)</P>

<P><B>Additional note, November, 2014:</B></P>

<P>See paper N4148.</P>

<P><B>Additional note, October, 2015:</B></P>

<P>Moved from "extension" to "open" status, along with
issue 1928, to allow reconsideration
by CWG.  It has been suggested that the triviality of a deleted
function should be irrelevant, since it cannot be used in any
event.  A possible change to implement that, more conservative than
the one proposed in N4148, would be:</P>

<BLOCKQUOTE>

<P>A trivially copyable class is a class that:</P>

<UL><LI><P>has no non-trivial, non-deleted copy constructors
(12.8 [class.copy]),</P></LI>

<LI><P>has no non-trivial, non-deleted move constructors
(12.8 [class.copy]),</P></LI>

<LI><P>has no non-trivial, non-deleted copy assignment operators
(13.5.3 [over.ass], 12.8 [class.copy]),</P></LI>

<LI><P>has no non-trivial, non-deleted move assignment operators
(13.5.3 [over.ass], 12.8 [class.copy]),</P></LI>

<LI><P>has at least one non-deleted copy or move constructor or
assignment operator, and</P></LI>

<LI><P>has a trivial, non-deleted destructor
(12.4 [class.dtor]).</P></LI>

</UL>

</BLOCKQUOTE>



<P><B>Proposed resolution (October, 2015):</B></P>

<P>Change 9 [class] paragraph 6 as follows:</P>

<BLOCKQUOTE>

<P>A <I>trivially copyable class</I> is a class<SPAN style="text-decoration:line-through;background-color:#FFA0A0"> that</SPAN>:</P>

<UL><LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">has no non-trivial copy constructors
(12.8 [class.copy]),</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">has no non-trivial move constructors
(12.8 [class.copy]),</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">has no non-trivial copy assignment operators
(13.5.3 [over.ass], 12.8 [class.copy]),</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">has no non-trivial move assignment operators
(13.5.3 [over.ass], 12.8 [class.copy]),
and</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">where each copy constructor, move constructor, copy
assignment operator, and move assignment operator
(12.8 [class.copy], 13.5.3 [over.ass]) is
either deleted or trivial,</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">that has at least one non-deleted copy constructor,
move constructor, copy assignment operator, or move
assignment operator, and</SPAN></P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">that</SPAN> has a trivial<SPAN style="font-weight:bold;background-color:#A0FFA0">, non-deleted</SPAN>
destructor (12.4 [class.dtor]).</P></LI>

</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="1895"></A><H4>1895.
  
Deleted conversions in conditional operator operands
</H4><B>Section: </B>5.16&#160; [expr.cond]
 &#160;&#160;&#160;

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

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

 <B>Date: </B>2014-03-17




<P>In an example like,</P>

<PRE>
  struct B;
  struct A { A(); A(B&amp;) = delete; operator B&amp;(); };
  struct B : A {} b;
  B &amp;c = true ? A() : b;
</PRE>

<P>the rules of 5.16 [expr.cond] paragraph 3 make this
ambiguous: <TT>A()</TT> can be implicitly converted to the type
&#8220;lvalue reference to <TT>B</TT>,&#8221; and <TT>b</TT> satisfies the
constraints to be converted to an <TT>A</TT> prvalue (it's of a type
derived from <TT>A</TT> and the cv-qualifiers are okay). Bullet 3 bullet 1
is clear that we do not actually try to create an <TT>A</TT> temporary
from <TT>b</TT>, so we don't notice that it invokes a deleted constructor
and rule out that conversion.</P>

<P>If the deleted conversion is in the other sense, the result is
unambiguous:</P>

<PRE>
  struct B;
  struct A { A(); A(B&amp;); operator B&amp;() = delete; };
  struct B : A {} b;
  B &amp;c = true ? A() : b;
</PRE>

<P><TT>A()</TT> can no longer be implicitly converted to the type
&#8220;lvalue reference to <TT>B</TT>&#8221;: since the declaration <TT>B
&amp;t = A();</TT> is not well formed (it invokes a deleted function),
there is no implicit conversion. So we unambiguously convert the third
operand to an <TT>A</TT> prvalue.</P>

<P>These should presumably either both be valid or both invalid.
EDG and gcc call both ambiguous.</P>

<P><B>Notes from the June, 2014 meeting:</B></P>

<P>The wording should be changed to handle the convertibility
test more like overload resolution: the conversion "exists" if
the conversion function is declared, but is ill-formed if it
would actually be used.</P>

<P><B>Proposed resolution (October, 2015):</B></P>

<OL><LI><P>Add the following as a new paragraph following
5.16 [expr.cond] paragraph 2:</P></LI>

<BLOCKQUOTE>

<SPAN style="font-weight:bold;background-color:#A0FFA0">Otherwise, if the second and third operand are glvalue
bit-fields of the same value category and of
types <I>cv1</I> <TT>T</TT> and
<I>cv2</I> <TT>T</TT>, respectively, the operands are
considered to be of type <I>cv</I> <TT>T</TT> for the
remainder of this section, where <I>cv</I> is the union
of <I>cv1</I> and <I>cv2</I>.</SPAN>

</BLOCKQUOTE>

<LI><P>Change 5.16 [expr.cond] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

<P>Otherwise, if the second and third operand have different
types and either has (possibly cv-qualified) class type, or
if both are glvalues of the same value category and the same
type except for cv-qualification, an attempt is made to
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">convert</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">form an implicit conversion sequence
(13.3.3.1 [over.best.ics]) from</SPAN> each of those
operands to the type of the other. <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I>
Properties such as access, whether an operand is a
bit-field, or whether a conversion function is deleted are
ignored for that determination. &#8212;<I>end
note</I>]</SPAN> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">The process for determining whether an
operand expression <TT>E1</TT> of type <TT>T1</TT> can be
converted to match an operand expression <TT>E2</TT> of
type <TT>T2</TT> is defined as follows:</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">Attempts
are made to form an implicit conversion sequence from an
operand expression <TT>E1</TT> of type <TT>T1</TT> to a
target type related to the type
<TT>T2</TT> of the operand expression <TT>E2</TT> as
follows:</SPAN></P>

<UL><LI><P>If <TT>E2</TT> is an lvalue<SPAN style="text-decoration:line-through;background-color:#FFA0A0">: <TT>E1</TT> can
be converted to match <TT>E2</TT> if <TT>E1</TT> can be
implicitly converted (Clause 4 [conv]) to the
type</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">, the target type is</SPAN> &#8220;lvalue
reference to <TT>T2</TT>&#8221;, subject to the constraint
that in the conversion the reference must bind directly
(8.5.3 [dcl.init.ref]) to an lvalue.</P></LI>

<LI><P>If <TT>E2</TT> is an xvalue<SPAN style="text-decoration:line-through;background-color:#FFA0A0">: <TT>E1</TT> can be
converted to match <TT>E2</TT> if <TT>E1</TT> can be
implicitly converted to the type</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">, the target type
is</SPAN> &#8220;rvalue reference to <TT>T2</TT>&#8221;,
subject to the constraint that the reference must bind
directly.</P></LI>

<LI><P>If <TT>E2</TT> is a prvalue or if neither of the
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">conversions</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">conversion sequences</SPAN> above
can be <SPAN style="text-decoration:line-through;background-color:#FFA0A0">done</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">formed</SPAN> and at least one of
the operands has (possibly cv-qualified) class
type:</P></LI>

<UL><LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">if <TT>E1</TT> and <TT>E2</TT> have class type,
and the underlying class types are the same or one is a base
class of the other: <TT>E1</TT> can be converted to
match <TT>E2</TT> if the class of <TT>T2</TT> is the same
type as, or a base class of, the class of <TT>T1</TT>, and the
cv-qualification of <TT>T2</TT> is the same cv-qualification as, or a
greater cv-qualification than, the cv-qualification of
<TT>T1</TT>. If the conversion is applied, <TT>E1</TT> is
changed to a prvalue of type <TT>T2</TT> by
copy-initializing a temporary of type <TT>T2</TT>
from <TT>E1</TT> and using that temporary as the converted
operand.</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">if <TT>T1</TT> and <TT>T2</TT> are the
same class type (ignoring cv-qualification), or one is a
base class of the other, and <TT>T2</TT> is at least as
cv-qualified as <TT>T1</TT>, the target type is
<TT>T2</TT>,</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">Otherwise (if <TT>E1</TT> or <TT>E2</TT> has a non-class
type, or if they both have class types but the underlying
classes are not the same and neither is a base class of the
other): <TT>E1</TT> can be converted to match <TT>E2</TT>
if <TT>E1</TT> can be implicitly converted to</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">otherwise, the target type is</SPAN> the type that
<TT>E2</TT> would have after applying the lvalue-to-rvalue
(4.1 [conv.lval]), array-to-pointer
(4.2 [conv.array]), and function-to-pointer
(4.3 [conv.func]) standard conversions.</P></LI>

</UL>

</UL>

<P>Using this process, it is determined whether <SPAN style="font-weight:bold;background-color:#A0FFA0">an
implicit conversion sequence can be formed from</SPAN> the
second operand <SPAN style="text-decoration:line-through;background-color:#FFA0A0">can be converted to match</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">to the target type determined for</SPAN> the third
operand, and <SPAN style="text-decoration:line-through;background-color:#FFA0A0">whether the third operand can be converted
to match the second operand</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">vice versa</SPAN>. If
both <SPAN style="text-decoration:line-through;background-color:#FFA0A0">can be converted</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">sequences can be
formed</SPAN>, or one <SPAN style="text-decoration:line-through;background-color:#FFA0A0">can be converted but the
conversion is</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">formed, but it is the</SPAN> ambiguous
<SPAN style="font-weight:bold;background-color:#A0FFA0">conversion sequence</SPAN>, the program is ill-formed. If
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">neither can be converted</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">no conversion
sequence can be formed</SPAN>, the operands are left
unchanged and further checking is performed as described
below. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">If exactly one conversion is
possible,</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">Otherwise, if exactly one conversion
sequence can be formed,</SPAN> that conversion is applied to
the chosen operand and the converted operand is used in
place of the original operand for the remainder of this
section. <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I> The conversion might be
ill-formed even if an implicit conversion sequence could
be formed. &#8212;<I>end note</I>]</SPAN></P>

</BLOCKQUOTE>

</OL>

<P>This resolution also resolves issue 1932.</P>

<BR><BR><HR><A NAME="1930"></A><H4>1930.
  
<I>init-declarator-list</I> vs <I>member-declarator-list</I>
</H4><B>Section: </B>7.1.1&#160; [dcl.stc]
 &#160;&#160;&#160;

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

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

 <B>Date: </B>2014-05-19




<P>According to 7.1.1 [dcl.stc] paragraph 1,</P>

<BLOCKQUOTE>

If a <I>storage-class-specifier</I> appears in a <I>decl-specifier-seq</I>,
there can be no <TT>typedef</TT> specifier in the
same <I>decl-specifier-seq</I> and the <I>init-declarator-list</I> of the
declaration shall not be empty...

</BLOCKQUOTE>

<P>This obviously should apply to <TT>mutable</TT> but does not
because <TT>mutable</TT> applies to <I>member-declarator-list</I>s,
not <I>init-declarator-list</I>s.  Similarly, in
7.1.6.1 [dcl.type.cv] paragraph 1,</P>

<BLOCKQUOTE>

If a <I>cv-qualifier</I> appears in a <I>decl-specifier-seq</I>,
the <I>init-declarator-list</I> of the declaration shall not be empty.

</BLOCKQUOTE>

<P>this should apply to member declarations as well.</P>

<P><B>Proposed resolution (October, 2015):</B></P>

<OL><LI><P>Change 7.1.1 [dcl.stc] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...If a <I>storage-class-specifier</I> appears in
a <I>decl-specifier-seq</I>, there can be
no <TT>typedef</TT> specifier in the
same <I>decl-specifier-seq</I> and
the <I>init-declarator-list</I> <SPAN style="font-weight:bold;background-color:#A0FFA0">or <I>member-declarator-list</I></SPAN>
of the declaration shall not be empty (except for an
anonymous union declared in a named namespace or in the
global namespace, which shall be declared <TT>static</TT>
(9.5 [class.union])). The <I>storage-class-specifier</I>
applies...

</BLOCKQUOTE>

<LI><P>Change 7.1.6.1 [dcl.type.cv] paragraph 1 as follows:</P></LI>

<BLOCKQUOTE>

...If a <I>cv-qualifier</I> appears in
a <I>decl-specifier-seq</I>, the <I>init-declarator-list</I>
<SPAN style="font-weight:bold;background-color:#A0FFA0">or <I>member-declarator-list</I></SPAN> of the
declaration shall not be empty. [<I>Note:</I>...

</BLOCKQUOTE>

</OL>

<P><B>Additional note, November, 2014:</B></P>

<P>The preceding resolution, which was advanced to "tentatively
ready" status during the review session following the November,
2014 (Urbana) meeting, introduces an apparently unintentional
conflict with 9.5 [class.union] paragraph 6 regarding
the requirements for anonymous unions in unnamed namespaces and has
been returned to "review" status to allow further discussion.</P>

<P><B>Notes from the October, 2015 meeting:</B></P>

<P>The proposed resolution was changed to address the preceding
concern.</P>

<BR><BR><HR><A NAME="1932"></A><H4>1932.
  
Bit-field results of conditional operators
</H4><B>Section: </B>5.16&#160; [expr.cond]
 &#160;&#160;&#160;

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

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

 <B>Date: </B>2014-02-21




<P>According to 5.16 [expr.cond] paragraph 3,</P>

<BLOCKQUOTE>

<P>if the second and third operand have different types and either has
(possibly cv-qualified) class type, or if both are glvalues of the same
value category and the same type except for cv-qualification, an attempt is
made to convert each of those operands to the type of the other. The
process for determining whether an operand expression <TT>E1</TT> of
type <TT>T1</TT> can be converted to match an operand
expression <TT>E2</TT> of type <TT>T2</TT> is defined as follows:</P>

<UL><LI><P>If E2 is an lvalue: <TT>E1</TT> can be converted to
match <TT>E2</TT> if <TT>E1</TT> can be implicitly converted (Clause
4 [conv]) to the type &#8220;lvalue reference
to <TT>T2</TT>&#8221;, subject to the constraint that in the conversion the
reference must bind directly (8.5.3 [dcl.init.ref]) to an
lvalue.</P></LI>

</UL>

</BLOCKQUOTE>

<P>If two bit-field glvalues have exactly the same scalar type, paragraph
3 does not apply (two non-class operands must differ in at least
cv-qualification).  For an example like</P>

<PRE>
  struct S {
    int i:3;
    const int j:4;
  } s;
  int k = true ? s.i : s.j;
</PRE>

<P>the condition is satisfied.  The intent is that <TT>S::i</TT> can be
converted to <TT>const int</TT> but <TT>S::j</TT> cannot be converted
to <TT>int</TT>, so the result should be a bit-field lvalue of
type <TT>const int</TT>.  However, the test for convertibility is phrased
in terms of direct reference binding, which is inapplicable to bit-fields,
resulting in neither conversion succeeding, leading to categorizing the
expression as ambiguous.</P>

<P><B>Proposed resolution (October, 2015):</B></P>

<P>This issue is resolved by the resolution of
issue 1895.</P>

<BR><BR><HR><A NAME="1955"></A><H4>1955.
  
<TT>#elif</TT> with invalid controlling expression
</H4><B>Section: </B>16.1&#160; [cpp.cond]
 &#160;&#160;&#160;

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

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

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




<P>An <TT>#elif</TT> is treated differently from an <TT>#else</TT>
followed immediately by an <TT>#if</TT>: assuming the preceding
<TT>#if</TT>'s condition was <TT>true</TT>, the condition in the
second <TT>#if</TT> need not be a valid <I>expression</I>, while
the condition in the <TT>#elif</TT> directive, though not evaluated,
still must be syntactically correct.</P>

<P><A HREF="http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_412.htm">
C DR 412</A> changes that for C; C++ should make the corresponding
change.</P>

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

<P>Change 16.1 [cpp.cond] paragraph 6 as follows:</P>

<BLOCKQUOTE>

Each directive's condition is checked in order. If it
evaluates to false (zero), the group that it controls is
skipped: directives are processed only through the name that
determines the directive in order to keep track of the level
of nested conditionals; the rest of the directives'
preprocessing tokens are ignored, as are the other
preprocessing tokens in the group. Only the first group
whose control condition evaluates to true (nonzero) is
processed<SPAN style="font-weight:bold;background-color:#A0FFA0">; any following groups are skipped and their
controlling directives are processed as if they were in a
group that is skipped</SPAN>. If none of the conditions...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="2001"></A><H4>2001.
  
<I>non-directive</I> is underspecified
</H4><B>Section: </B>16&#160; [cpp]
 &#160;&#160;&#160;

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

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

 <B>Date: </B>2014-09-10




<P>The Standard needs to describe <I>non-directive</I>s more fully,
e.g., whether they are ill-formed, conditionally-supported, etc.
Since they are, in fact, directives, a different name might also be
in order.</P>

<P><B>Proposed resolution (October, 2015):</B></P>

<OL><LI><P>Change 16 [cpp] paragraph 1 as follows:</P></LI>

<UL><I>group-part:</I>
<UL><I>if-section</I><BR>
<I>control-line</I><BR>
<I>text-line</I><BR>
<TT>#</TT> <I><SPAN style="text-decoration:line-through;background-color:#FFA0A0">non-directive</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">conditionally-supported-directive</SPAN></I>
</UL>
...<BR>
<I><SPAN style="text-decoration:line-through;background-color:#FFA0A0">non-directive</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">conditionally-supported-directive</SPAN>:</I>
<UL><I>pp-tokens new-line</I>
</UL>
</UL>

<LI><P>Change 16 [cpp] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

A text line shall not begin with a <TT>#</TT> preprocessing
token. A <I><SPAN style="text-decoration:line-through;background-color:#FFA0A0">non-directive</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">conditionally-supported-directive</SPAN></I> shall not begin with any
of the directive names appearing in the syntax. <SPAN style="font-weight:bold;background-color:#A0FFA0">A
<I>conditionally-supported-directive</I> is conditionally supported with
implementation-defined semantics.</SPAN>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="2008"></A><H4>2008.
  
Default <I>template-argument</I>s underspecified
</H4><B>Section: </B>14.3&#160; [temp.arg]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Andrew Sutton
 &#160;&#160;&#160;

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




<P><B>Proposed resolution, October, 2015:</B></P>

<P>Add the following as a new paragraph after 14.3 [temp.arg]
paragraph 7:</P>

<BLOCKQUOTE>

<P>When the template in a <I>template-id</I> is an overloaded
function template...</P>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">When a <I>simple-template-id</I> does not name a function,
a default <I>template-argument</I> is implicitly instantiated
(14.7.1 [temp.inst]) when the value of that default
argument is needed. [<I>Example:</I></SPAN></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  template&lt;typename T, typename U = int&gt; struct S { };
  S&lt;bool&gt;* p; //<SPAN style="font-family:Times;font-style:italic"> the type of </SPAN>p<SPAN style="font-family:Times;font-style:italic"> is </SPAN>S&lt;bool, int&gt;*</SPAN>
</PRE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">The default argument for <TT>U</TT> is instantiated to form the
type <TT>S&lt;bool, int&gt;*</TT>. &#8212;<I>end example</I>]</SPAN></P>

</BLOCKQUOTE>

<P><B>Notes from the November, 2014 meeting:</B></P>

<P>The preceding was extracted from the wording of the
<I>Concepts Lite</I> draft Technical Specification.</P>

<BR><BR><HR><A NAME="2017"></A><H4>2017.
  
Flowing off end is not equivalent to no-expression return
</H4><B>Section: </B>6.6.3&#160; [stmt.return]
 &#160;&#160;&#160;

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

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

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


<P>According to 6.6.3 [stmt.return] paragraph 2,</P>

<BLOCKQUOTE>

Flowing off the end of a function is equivalent to a <TT>return</TT>
with no value...

</BLOCKQUOTE>

<P>This is not correct, since a <TT>return</TT> with no value is
ill-formed in a value-returning function but flowing off the end
results in undefined behavior.</P>

<P><B>Proposed resolution (May, 2015): [SUPERSEDED]</B></P>

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

<BLOCKQUOTE>

...Flowing off the end of a <SPAN style="font-weight:bold;background-color:#A0FFA0">value-returning</SPAN>
function is <SPAN style="font-weight:bold;background-color:#A0FFA0">undefined behavior.  Flowing off the end of
any other function is</SPAN> equivalent to a return with no
value<SPAN style="text-decoration:line-through;background-color:#FFA0A0">; this results in undefined behavior in a
value-returning function</SPAN>.

</BLOCKQUOTE>

<P><B>Additional notes, October, 2015:</B></P>

<P>There is similar wording in 15.3 [except.handle]
paragraph 14.  Also, it might be better to avoid the
use of the word &#8220;value&#8221;, since it is currently
not clearly defined.</P>

<P><B>Proposed resolution (October, 2015):</B></P>

<OL><LI><P>Change 3.6.1 [basic.start.main] paragraph 5 as follows:</P></LI>

<BLOCKQUOTE>

<P>A return statement in <TT>main</TT> has the effect of
leaving the main function (destroying any objects with
automatic storage duration) and calling <TT>std::exit</TT>
with the return value as the argument. If
control <SPAN style="text-decoration:line-through;background-color:#FFA0A0">reaches</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">flows off</SPAN> the end
of <SPAN style="font-weight:bold;background-color:#A0FFA0">the <I>compound-statement</I>
of</SPAN> <TT>main</TT><SPAN style="text-decoration:line-through;background-color:#FFA0A0"> without encountering
a <TT>return</TT> statement</SPAN>, the effect is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">that
of executing</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">equivalent to a <TT>return</TT> with
operand <TT>0</TT> (see also
15.3 [except.handle]).</SPAN></P>

<PRE>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">  return 0;</SPAN>
</PRE>

</BLOCKQUOTE>

<LI><P>Change 6.6.3 [stmt.return] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

...Flowing off the end of a function <SPAN style="font-weight:bold;background-color:#A0FFA0">with a void return
type</SPAN> is equivalent to a <TT>return</TT> with
no <SPAN style="text-decoration:line-through;background-color:#FFA0A0">value; this results in undefined behavior in a
value-returning
function</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">operand</SPAN>. <SPAN style="font-weight:bold;background-color:#A0FFA0">Otherwise, flowing
off the end of a function other than <TT>main</TT>
(3.6.1 [basic.start.main] results in undefined
behavior.</SPAN>

</BLOCKQUOTE>

<LI><P>Change 15.3 [except.handle] paragraph 14 as follows:</P></LI>

<BLOCKQUOTE>

The currently handled exception is rethrown if control
reaches the end of a handler of
the <I>function-try-block</I> of a constructor or
destructor. Otherwise, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a function returns when control
reaches the end of a handler for
the <I>function-try-block</I>
(6.6.3 [stmt.return]). Flowing off the end of
a <I>function-try-block</I> is equivalent to
a <TT>return</TT> with no value; this results in undefined
behavior in a value-returning function
(6.6.3 [stmt.return])</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">flowing off the
end of the <I>compound-statement</I> of a <I>handler</I>
of a <I>function-try-block</I> is equivalent to flowing
off the end of the <I>compound-statement</I> of that
function (see 6.6.3 [stmt.return])</SPAN>.

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="2082"></A><H4>2082.
  
Referring to parameters in unevaluated operands of default arguments
</H4><B>Section: </B>8.3.6&#160; [dcl.fct.default]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Faisal Vali
 &#160;&#160;&#160;

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




<P>According to 8.3.6 [dcl.fct.default] paragraph 9,</P>

<BLOCKQUOTE>

A default argument is evaluated each time the function is
called with no argument for the corresponding parameter. The
order of evaluation of function arguments is
unspecified. Consequently, parameters of a function shall
not be used in a default argument, even if they are not
evaluated.

</BLOCKQUOTE>

<P>This prohibits use of parameters in unevaluated operands, e.g.,</P>

<PRE>
  void foo(int a = decltype(a){});
</PRE>

<P>This wording predates the concept of &#8220;unevaluated
operands&#8221; (the phrase &#8220;not evaluated&#8221; refers
to calls to the function where an actual argument is supplied and
thus the default argument is not used, not to unevaluated
operands) and should not apply to such cases.</P>

<P><B>Proposed resolution (October, 2015):</B></P>

<OL><LI><P>Change 8.3.6 [dcl.fct.default] paragraph 7 as follows:</P></LI>

<BLOCKQUOTE>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">Local variables</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">A local variable</SPAN>
shall not <SPAN style="text-decoration:line-through;background-color:#FFA0A0">be used</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">appear as a
potentially-evaluated expression</SPAN> in a default
argument. [<I>Example:</I></P>

<PRE>
  void f() {
    int i;
    extern void g(int x = i);           //<SPAN style="font-family:Times;font-style:italic"><SPAN style="font-weight:bold;background-color:#A0FFA0"> </SPAN>error</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">    extern void h(int x = sizeof(i));   //<SPAN style="font-family:Times;font-style:italic"> OK</SPAN></SPAN>
    //<SPAN style="font-family:Times;font-style:italic"> ...</SPAN>
  }
</PRE>

<P>&#8212;<I>end example</I>]</P>

</BLOCKQUOTE>

<LI><P>Change 8.3.6 [dcl.fct.default] paragraph 8 as follows:</P></LI>

<BLOCKQUOTE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I></SPAN> The
keyword <TT>this</TT> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">shall</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">may</SPAN>
not <SPAN style="text-decoration:line-through;background-color:#FFA0A0">be used</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">appear</SPAN> in a default
argument of a member function<SPAN style="font-weight:bold;background-color:#A0FFA0">; see
5.1.1 [expr.prim.general]</SPAN>. [<I>Example:</I></P>

<PRE>
  class A {
    void f(A* p = this) { } //<SPAN style="font-family:Times;font-style:italic"> error</SPAN>
  };
</PRE>

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

</BLOCKQUOTE>

<LI><P>Change 8.3.6 [dcl.fct.default] paragraph 9 as follows:</P></LI>

<BLOCKQUOTE>

<P>A default argument is evaluated each time the function is
called with no argument for the corresponding
parameter. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">The order of evaluation of function
arguments is unspecified. Consequently, parameters of a
function shall not be used in a default argument, even if
they are not evaluated.</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">A parameter shall not
appear as a potentially-evaluated expression in a default
argument.</SPAN> Parameters of a function declared before a
default argument are in scope and can hide namespace and
class member names. [<I>Example:</I></P>

<PRE>
  int a;
  int f(int a, int b = a);         //<SPAN style="font-family:Times;font-style:italic"> error: parameter </SPAN>a
                                   //<SPAN style="font-family:Times;font-style:italic"> used as default argument</SPAN>
  typedef int I;
  int g(float I, int b = I(2));    //<SPAN style="font-family:Times;font-style:italic"> error: parameter </SPAN>I<SPAN style="font-family:Times;font-style:italic"> found</SPAN>
  int h(int a, int b = sizeof(a)); //<SPAN style="font-family:Times;font-style:italic"> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">error, parameter </SPAN></SPAN><SPAN style="text-decoration:line-through;background-color:#FFA0A0">a</SPAN><SPAN style="font-family:Times;font-style:italic"><SPAN style="text-decoration:line-through;background-color:#FFA0A0"> used</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">OK, unevaluated operand</SPAN></SPAN>
  <SPAN style="text-decoration:line-through;background-color:#FFA0A0">                                   //<SPAN style="font-family:Times;font-style:italic"> in default argument</SPAN></SPAN>
</PRE>

<P>&#8212;<I>end example</I>] <SPAN style="text-decoration:line-through;background-color:#FFA0A0">Similarly,
a</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">A</SPAN> non-static member shall not <SPAN style="text-decoration:line-through;background-color:#FFA0A0">be
used</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">appear</SPAN> in a default argument<SPAN style="text-decoration:line-through;background-color:#FFA0A0">,
even if it is not evaluated,</SPAN> unless it appears as
the <I>id-expression</I> of a class member access expression
(5.2.5 [expr.ref]) or unless it is used to form a
pointer to member
(5.3.1 [expr.unary.op]). [<I>Example:</I>...</P>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="2084"></A><H4>2084.
  
NSDMIs and deleted union default constructors
</H4><B>Section: </B>12.1&#160; [class.ctor]
 &#160;&#160;&#160;

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

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

 <B>Date: </B>2015-02-12


<P>According to 12.1 [class.ctor] paragraph 4 says,</P>

<BLOCKQUOTE>

<P>A defaulted default constructor for class <TT>X</TT> is defined as
deleted if:</P>

<UL><LI><P><TT>X</TT> is a union-like class that has a
variant member with a non-trivial default
constructor,</P></LI>

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

</UL>

</BLOCKQUOTE>

<P>This should make the following example ill-formed:</P>

<PRE>
  struct S {
    S();
  };
  union U {
    S s{};
  } u;
</PRE>

<P>because the default constructor of <TT>U</TT> is deleted.  However,
both clang and g++ accept this without error.  Should the rule be
relaxed for a union with an NSDMI?</P>

<P><B>Notes from the May, 2015 meeting:</B></P>

<P>An NSDMI is basically syntactic sugar for a
<I>mem-initializer</I>, so the presence of one should be
treated as if a user-declared default constructor were present.</P>

<P><B>Proposed resolution (October, 2015):</B></P>

<P>Change 12.1 [class.ctor] paragraph 4 as follows:</P>

<BLOCKQUOTE>

<P>...A defaulted default constructor for class <TT>X</TT> is defined as
deleted if:</P>

<UL><LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>X</TT> is a union that has a variant
member with a non-trivial default constructor and no variant
member of <TT>X</TT> has a default member
initializer,</SPAN></P></LI>

<LI><P><TT>X</TT> is
a <SPAN style="text-decoration:line-through;background-color:#FFA0A0">union-like</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">non-union</SPAN> class that has
a variant member <SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>M</TT></SPAN> with a non-trivial default
constructor <SPAN style="font-weight:bold;background-color:#A0FFA0">and no variant member of the anonymous union
containing <TT>M</TT> has a default member initializer</SPAN>,</P></LI>

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

</UL>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="2093"></A><H4>2093.
  
Qualification conversion for pointer-to-member handler matching
</H4><B>Section: </B>15.3&#160; [except.handle]
 &#160;&#160;&#160;

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

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

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


<P>The criteria for matching an exception handler in
15.3 [except.handle] paragraph 3 include a qualification
conversion for a handler of pointer or reference to pointer type
but not for a handler of pointer-to-member type.  However, current
implementations permit such conversions.</P>

<P><B>Proposed resolution (October, 2015):</B></P>

<P>Change 15.3 [except.handle] bullet 3.3 as follows:</P>

<BLOCKQUOTE>

<P>A <I>handler</I> is a match for an exception object of
type <TT>E</TT> if</P>

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

<LI>

<P>the <I>handler</I> is of type <I>cv</I> <TT>T</TT>
or <TT>const T&amp;</TT> where <TT>T</TT> is a
pointer <SPAN style="font-weight:bold;background-color:#A0FFA0">or pointer to member</SPAN> type and <TT>E</TT>
is a pointer <SPAN style="font-weight:bold;background-color:#A0FFA0">or pointer to member</SPAN> type that can
be converted to <TT>T</TT> by either or both of</P></LI>

<UL><LI><P>a standard pointer conversion (4.10 [conv.ptr])
not involving conversions to pointers to private or
protected or ambiguous classes</P></LI>

<LI><P>a qualification
conversion <SPAN style="font-weight:bold;background-color:#A0FFA0">(4.4 [conv.qual])</SPAN>,
or</P></LI>

</UL>

<LI><P>the <I>handler</I> is...</P></LI>

</UL>

</BLOCKQUOTE>

<P><B>Notes from the October, 2015 meeting:</B></P>

<P>This resolution should not be adopted as a Defect Report,
only a change in the working paper for future revisions of
the Standard, because it could silently change the behavior
of well-defined programs in implementations that conform to
the existing wording.</P>

<BR><BR><HR><A NAME="2099"></A><H4>2099.
  
Inferring the bound of an array static data member
</H4><B>Section: </B>8.3.4&#160; [dcl.array]
 &#160;&#160;&#160;

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

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

 <B>Date: </B>2015-03-15




<P>According to 8.3.4 [dcl.array] paragraph 3,</P>

<BLOCKQUOTE>

An array bound may also be omitted when the declarator is
followed by an <I>initializer</I> (8.5 [dcl.init]). In
this case the bound is calculated from the number of initial
elements...

</BLOCKQUOTE>

<P>However, the grammar for <I>member-declarator</I> uses
<I>brace-or-equal-initializer</I>, not <I>initializer</I>, so
the following is ill-formed:</P>

<PRE>
  struct X {
    static constexpr int arr[] = { 1, 2, 3 };
  };
</PRE>

<P><B>Proposed resolution (October, 2015):</B></P>

<P>Change 8.3.4 [dcl.array] paragraph 3 as follows:</P>

<BLOCKQUOTE>

...An array bound may also be omitted when the declarator is followed by an
<I>initializer</I> (8.5 [dcl.init]) <SPAN style="font-weight:bold;background-color:#A0FFA0">or when a declarator for
a static data member is followed by a <I>brace-or-equal-initializer</I>
(9.2 [class.mem])</SPAN>. In <SPAN style="text-decoration:line-through;background-color:#FFA0A0">this case</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">both
cases</SPAN> the bound is calculated from the number of initial elements...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="2124"></A><H4>2124.
  
Signature of constructor template
</H4><B>Section: </B>1.3.22&#160; [defns.signature.member.templ]
 &#160;&#160;&#160;

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

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

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




<P>According to 1.3.22 [defns.signature.member.templ], the signature of a class
member function template includes:</P>

<BLOCKQUOTE>

name, parameter type list (8.3.5 [dcl.fct]), class of which the
function is a member, <I>cv</I>-qualifiers (if any), <I>ref-qualifier</I> (if
any), return type, and template parameter list

</BLOCKQUOTE>

<P>However, a constructor template does not have a return type.  This
may be relevant to friend declaration matching.</P>

<P><B>Proposed resolution (October, 2015):</B></P>

<P>Change 1.3.22 [defns.signature.member.templ] as follows:</P>

<BLOCKQUOTE>

<B>signature</B><BR>
&lt;class member function template&gt; name, parameter type list (8.3.5 [dcl.fct]), class of which the function is a member,
<I>cv-qualifier</I>s (if any), <I>ref-qualifier</I> (if
any), return type <SPAN style="font-weight:bold;background-color:#A0FFA0">(if any)</SPAN>, and template parameter list

</BLOCKQUOTE>

<BR><BR><HR><A NAME="2130"></A><H4>2130.
  
Over-aligned types in <I>new-expression</I>s
</H4><B>Section: </B>5.3.4&#160; [expr.new]
 &#160;&#160;&#160;

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

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

 <B>Date: </B>2015-05-28




<P>According to 5.3.4 [expr.new] paragraph 1,</P>

<BLOCKQUOTE>

It is implementation-defined whether over-aligned types
are supported (3.11 [basic.align]).

</BLOCKQUOTE>

<P>However, there is no mechanism for informing an allocation
function of the required alignment for over-aligned types.
Nevertheless, 3.11 [basic.align] paragraph 9 says:</P>

<BLOCKQUOTE>

Additionally, a request for runtime allocation of dynamic
storage for which the requested alignment cannot be honored
shall be treated as an allocation failure.

</BLOCKQUOTE>

<P>This seems contradictory.</P>

<P><B>Proposed resolution (October, 2015):</B></P>

<P>Change 3.11 [basic.align] paragraph 9 as follows:</P>

<BLOCKQUOTE>

If a request for a specific extended alignment in a specific
context is not supported by an implementation, the program
is ill-formed. <SPAN style="text-decoration:line-through;background-color:#FFA0A0">Additionally, a request for runtime
allocation of dynamic storage for which the requested
alignment cannot be honored shall be treated as an
allocation failure.</SPAN>

</BLOCKQUOTE>

<BR><BR><HR><A NAME="2157"></A><H4>2157.
  
Further disambiguation of enumeration <I>elaborated-type-specifier</I>
</H4><B>Section: </B>7.1.6.3&#160; [dcl.type.elab]
 &#160;&#160;&#160;

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

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

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


<P>The resolution of issue 1966 does not
apply to the case where the enumeration name is qualified, e.g.,</P>

<PRE>
  enum E : int;
  struct X {
    enum ::E : int();
  };
</PRE>

<P><B>Proposed resolution (October, 2015):</B></P>

<P>Change 7.2 [dcl.enum] paragraph 1 as follows:</P>

<BLOCKQUOTE>

...A <TT>:</TT> following &#8220;<TT>enum</TT>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><I>nested-name-specifier<SUB>opt</SUB></I></SPAN>
<I>identifier</I>&#8221; within the <I>decl-specifier-seq</I> of
a <I>member-declaration</I> is parsed as part of
an <I>enum-base</I>. [<I>Note:</I> This resolves a potential
ambiguity...

</BLOCKQUOTE>

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