<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=us-ascii">
<TITLE>
    Core "tentatively ready" Issues
   </TITLE>
</HEAD>
<BODY>
<TABLE ALIGN="RIGHT" CELLSPACING="0" CELLPADDING="0">
<TR>
<TD ALIGN="RIGHT">
      Document number:
     </TD>
<TD>
       &#160;P1114R0</TD>
</TR>
<TR>
<TD ALIGN="RIGHT">
      Date:
     </TD>
<TD>
      &#160;2018-06-05</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 Working Group "tentatively ready" Issues
     for the
     June, 2018 (Rapperswil) 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/2017/n4700.pdf">WG21 N4700</A>.
   </P>
<HR><A NAME="2233"></A><H4>2233.
  
Function parameter packs following default arguments
</H4><B>Section: </B>11.3.6&#160; [dcl.fct.default]
 &#160;&#160;&#160;

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

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

 <B>Date: </B>2016-02-25




<P>The resolution of issue 777 attempts to
make this valid:</P>

<PRE>
   template&lt;typename ...T&gt; void f(int n = 0, T ...t); 
</PRE>

<P>However, it fails to do so, since any parameters resulting from the
expansion of the pack would be ordinary parameters without default
arguments following a parameter with a default argument, which is
ill-formed. Thus only an empty pack would be usable with such a
declaration, which violates the restriction against such contexts in
17.7 [temp.res] bullet 8.3.</P>

<P><B>Proposed resolution, February, 2018:</B></P>

<OL><LI><P>Change 8.2.2 [expr.call] paragraph 4 as follows:</P></LI>

<BLOCKQUOTE>

<P>When a function is called, each parameter (11.3.5 [dcl.fct])
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">shall be</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">is</SPAN> initialized (11.6 [dcl.init],
15.8 [class.copy], 15.1 [class.ctor]) with its
corresponding argument. <SPAN style="font-weight:bold;background-color:#A0FFA0">If there is no corresponding argument, the default argument for the parameter is used; the program is ill-formed if one is not present. [<I>Example:</I></SPAN></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  template&lt;typename ...T&gt; int f(int n = 0, T ...t);
  int x = f&lt;int&gt;();   //<SPAN style="font-family:Times;font-style:italic"> error: no argument for second function parameter</SPAN></SPAN>
</PRE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end example</I>]</SPAN> If the function is a non-static
member function, the this parameter of the function
(12.2.2.1 [class.this]) <SPAN style="text-decoration:line-through;background-color:#FFA0A0">shall be</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">is</SPAN>
initialized with a pointer to the object of the call, converted as if by an
explicit type conversion (8.4 [expr.cast]). [<I>Note:</I> There is
no access or ambiguity checking...</P>

</BLOCKQUOTE>

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

<BLOCKQUOTE>

If an <I>initializer-clause</I> is specified in
a <I>parameter-declaration</I> this <I>initializer-clause</I> is used as a
default argument. <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I></SPAN> Default arguments will be used
in calls where trailing arguments are
missing <SPAN style="font-weight:bold;background-color:#A0FFA0">(8.2.2 [expr.call])</SPAN>. <SPAN style="font-weight:bold;background-color:#A0FFA0">&#8212;<I>end
note</I>]</SPAN>

</BLOCKQUOTE>

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

<BLOCKQUOTE>

<P>For non-template functions, default arguments can be added in later
declarations of a function in the same scope. Declarations in different
scopes have completely distinct sets of default arguments. That is,
declarations in inner scopes do not acquire default arguments from
declarations in outer scopes, and vice versa. In a given function
declaration, each parameter subsequent to a parameter with a default
argument shall have a default argument supplied in this or a previous
declaration<SPAN style="font-weight:bold;background-color:#A0FFA0">, unless the parameter was expanded from a parameter
pack,</SPAN> or shall be a function parameter pack.  A default argument
shall not be redefined by a later declaration (not even to the same
value). [<I>Example:</I></P>

<PRE>
  void g(int = 0, ...);   //<SPAN style="font-family:Times;font-style:italic"> OK, ellipsis is not a parameter so it can follow</SPAN>
                          //<SPAN style="font-family:Times;font-style:italic"> a parameter with a default argument</SPAN>
  void f(int, int);
  void f(int, int = 7);
  void h() {
    f(3);                 //<SPAN style="font-family:Times;font-style:italic"> OK, calls </SPAN>f(3, 7)
    void f(int = 1, int); //<SPAN style="font-family:Times;font-style:italic"> error: does not use default from surrounding scope</SPAN>
  }
  void m() {
    void f(int, int);     //<SPAN style="font-family:Times;font-style:italic"> has no defaults</SPAN>
    f(4);                 //<SPAN style="font-family:Times;font-style:italic"> error: wrong number of arguments</SPAN>
    void f(int, int = 5); //<SPAN style="font-family:Times;font-style:italic"> OK</SPAN>
    f(4); //<SPAN style="font-family:Times;font-style:italic"> OK, calls </SPAN>f(4, 5);
    void f(int, int = 5); //<SPAN style="font-family:Times;font-style:italic"> error: cannot redefine, even to same value</SPAN>
  }
  void n() {
    f(6);                 //<SPAN style="font-family:Times;font-style:italic"> OK, calls </SPAN>f(6, 7)
  }
<SPAN style="font-weight:bold;background-color:#A0FFA0">  template&lt;class ... T&gt; struct C {
    void f(int n = 0, T...);
  };
  C&lt;int&gt; c;               //<SPAN style="font-family:Times;font-style:italic"> OK; instantiates declaration </SPAN>void C::f(int n = 0, int)</SPAN>
</PRE>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="2249"></A><H4>2249.
  
<I>identifier</I>s and <I>id-expression</I>s
</H4><B>Section: </B>8.1.4.1&#160; [expr.prim.id.unqual]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Robert Haberlach
 &#160;&#160;&#160;

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


<P>According to 8.1.4.1 [expr.prim.id.unqual] paragraph 1,</P>

<BLOCKQUOTE>

An <I>identifier</I> is an <I>id-expression</I> provided it has been
suitably declared (Clause 10 [dcl.dcl]).

</BLOCKQUOTE>

<P>Not only is an <I>identifier</I> an <I>id-expression</I> by
(grammatical) definition, <I>declarator-id</I> is defined in terms of
<I>id-expression</I>, which makes this circular. If the intention was
to disallow use of undeclared identifiers as primary expressions, this
should be altered accordingly.
</P>

<P><B>Proposed resolution, February, 2018:</B></P>

<P>Change 8.1.4.1 [expr.prim.id.unqual] paragraph 1 as follows:</P>

<BLOCKQUOTE>

An <I>identifier</I> is <SPAN style="font-weight:bold;background-color:#A0FFA0">only</SPAN> an <I>id-expression</I>
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">provided</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">if</SPAN> it has been suitably declared (Clause
10 [dcl.dcl]) <SPAN style="font-weight:bold;background-color:#A0FFA0">or if it appears as part of a
<I>declarator-id</I> (Clause 11 [dcl.decl])</SPAN>. [<I>Note:</I>
For <I>operator-function-id</I>s, see...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="2285"></A><H4>2285.
  
Issues with structured bindings
</H4><B>Section: </B>11.5&#160; [dcl.struct.bind]
 &#160;&#160;&#160;

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

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

 <B>Date: </B>2016-07-01




<OL><LI><P>What is the point of declaration of a name introduced by a
structured binding? If it's the point at which it appears, we're missing a
rule to make it ill-formed to reference the name before its type is deduced
(similar to what we have for 'auto').  [Suggestion: point of declaration is
after the <I>identifier-list</I>, program is ill-formed if the name is
mentioned before the end of the initializer.]</P></LI>

<LI><P>Are structured bindings permitted at namespace scope? There doesn't
seem to be a rule against that. If so, what's their linkage? Is it
intentional that <TT>static</TT> , <TT>extern</TT> are disallowed? Should
we only allow automatic storage duration?  [Suggestion: only permit
automatic storage duration, per the design paper.]</P></LI>

<LI><P>(If the answer to 2 is yes...) is the declaration in a variable
template permitted to use structured bindings? If so, how do you name the
result?  (The bindings themselves aren't introduced
as <I>template-name</I>s by the current wording.) If not, we're missing a
restriction on that.  [Suggestion: no to question 2.]</P></LI>

<LI><P>Did we intend to guarantee that the object whose members are denoted
by bindings is kept "together":</P></LI>

<PRE>
   auto f() -&gt; int (&amp;)[2]; 
   auto [x, y] = f(); 
   assert(&amp;x + 1 == &amp;y); //<SPAN style="font-family:Times;font-style:italic"> ok? </SPAN>

   struct S { int a, b, c; }; //<SPAN style="font-family:Times;font-style:italic"> standard-layout </SPAN>
   auto [a,b,c] = S(); 
   assert(&amp;((S*)&amp;a)-&gt;b == &amp;b); //<SPAN style="font-family:Times;font-style:italic"> ok? </SPAN>
</PRE>

<P>(If yes, this means we can't synthesize independent variables for each
element of an array or struct that's bound in this way, and it's harder to
remove dead components of a destructured object.) Obviously we may need to
keep the object together if it has a non-trivial destructor.  [Suggestion:
do not allow reaching the complete object from a binding.]</P>

<LI><P>Should the copy-&gt;move promotion be permitted for a return of a
structured binding?</P></LI>

<PRE>
   struct A { string s; int n; }; 
   string f() { 
     auto [s,n] = A(); 
     return s; //<SPAN style="font-family:Times;font-style:italic"> copy required here? </SPAN>
   }
</PRE>

<P>[Suggestion: allow promotion to move -- as if the binding were a real local
variable -- if the implicit underlying variable is not a reference. Maybe
also allow NRVO, depending on answer to question 8.]</P>

</OL>

<P><B>Notes from the April, 2017 teleconference:</B></P>

<P>Items 1 and 3 are core issues; item 4 is NAD - the bindings are kept
together, which is implied by the existing rules about copying the object
into a hidden temporary. The remaining items are questions for EWG and
new items in "extension" status will be opened for them.</P>

<P><B>Proposed resolution, February, 2018:</B></P>

<OL><LI><P>Change 6.3.2 [basic.scope.pdecl] paragraph 9 as follows and
add the following new paragraph thereafter:</P></LI>

<BLOCKQUOTE>

<P>The point of declaration for a function-local predefined variable
(<SPAN style="text-decoration:line-through;background-color:#FFA0A0">11.4 [dcl.fct.def]</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">11.4.1 [dcl.fct.def.general]</SPAN>)
is immediately before the <I>function-body</I> of a function definition.</P>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">The point of declaration of a structured binding
(11.5 [dcl.struct.bind]) is immediately after the
<I>identifier-list</I> of the structured binding declaration.</SPAN></P>

</BLOCKQUOTE>

<LI><P>Add the following as a new paragraph following
11.5 [dcl.struct.bind] paragraph 1:</P></LI>

<BLOCKQUOTE>

<P>...taken from the corresponding structured binding declaration. The type
of the <I>id-expression</I> <TT>e</TT> is called <TT>E</TT>. [<I>Note:</I>
E is never a reference type (Clause 8 [expr]). &#8212;<I>end
note</I>]</P>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">If the <I>initializer</I> refers to one of the names introduced
by the structured binding declaration, the program is ill-formed.</SPAN></P>

</BLOCKQUOTE>

</OL>

<P>(Note: In response to item 3, the current wording of
17 [temp] paragraph 1 does not allow templated structured
binding declarations, and no change is being proposed.)</P>

<BR><BR><HR><A NAME="2351"></A><H4>2351.
  
<TT>void{}</TT>
</H4><B>Section: </B>8.2.3&#160; [expr.type.conv]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Peter Dimov
 &#160;&#160;&#160;

 <B>Date: </B>2017-06-26


<P>According to 8.2.3 [expr.type.conv] paragraph 2,</P>

<BLOCKQUOTE>

If the initializer is a parenthesized single expression, the type
conversion expression is equivalent to the corresponding cast expression
(8.4 [expr.cast]). Otherwise, if the type is <I>cv</I>
<TT>void</TT> and the initializer is <TT>()</TT> , the expression is a
prvalue of the specified type that performs no initialization. Otherwise,
the expression is a prvalue of the specified type whose result object is
direct-initialized (11.6 [dcl.init]) with the initializer. For an
expression of the form <TT>T()</TT>, <TT>T</TT> shall not be an array type.

</BLOCKQUOTE>

<P>It seems an oversight that <TT>void{}</TT> is not treated like
<TT>void()</TT>.</P>

<P><B>Proposed resolution, April, 2018:</B></P>

<P>Change 8.2.3 [expr.type.conv] paragraph 2 as follows:</P>

<BLOCKQUOTE>

...Otherwise, if the type is <I>cv</I> <TT>void</TT> and the initializer is
<TT>()</TT> <SPAN style="font-weight:bold;background-color:#A0FFA0">or <TT>{}</TT></SPAN>, the expression is a prvalue of the
specified type that performs no initialization. Otherwise...

</BLOCKQUOTE>

<BR><BR><HR><A NAME="2356"></A><H4>2356.
  
Base class copy and move constructors should not be inherited
</H4><B>Section: </B>16.3.1&#160; [over.match.funcs]
 &#160;&#160;&#160;

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

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

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


<P>Base class copy and move constructors brought into a derived class via a
<I>using-declaration</I> should not be considered by overload resolution
when constructing a derived class object.</P>

<P><B>Proposed resolution, February, 2018:</B></P>

<P>Change 16.3.1 [over.match.funcs] paragraph 8 as follows:</P>

<BLOCKQUOTE>

<P>A defaulted move special function (15.8 [class.copy]) that is
defined as deleted is excluded from the set of candidate functions in all
contexts. <SPAN style="font-weight:bold;background-color:#A0FFA0">A constructor inherited from class type <TT>C</TT>
(15.6.3 [class.inhctor.init]) that has a first parameter of type
&#8220;reference to <I>cv1</I> <TT>P</TT>&#8221; (including such a
constructor instantiated from a template) is excluded from the set of
candidate functions when constructing an object of type <I>cv2</I>
<TT>D</TT> if the argument list has exactly one argument and <TT>C</TT>
is reference-related to <TT>P</TT> and <TT>P</TT> is reference-related
to <TT>D</TT>. [<I>Example:</I></SPAN></P>

<PRE>
<SPAN style="font-weight:bold;background-color:#A0FFA0">  struct A {
    A();
    A(A &amp;&amp;);                        //<SPAN style="font-family:Times;font-style:italic"> #1</SPAN>
    template&lt;typename T&gt; A(T &amp;&amp;);   //<SPAN style="font-family:Times;font-style:italic"> #2</SPAN>
  };
  struct B : A {
    using A::A;
    B(const B &amp;);                   //<SPAN style="font-family:Times;font-style:italic"> #3</SPAN>
    B(B &amp;&amp;) = default;              //<SPAN style="font-family:Times;font-style:italic"> #4, implicitly deleted</SPAN>

    struct X { X(X &amp;&amp;) = delete; } x;
  };
  extern B b1;
  B b2 = static_cast&lt;B&amp;&amp;&gt;(b1);      //<SPAN style="font-family:Times;font-style:italic"> calls #3: #1, #2, and #4 are not viable</SPAN>
  struct C { operator B&amp;&amp;(); };
  B b3 = C();                       //<SPAN style="font-family:Times;font-style:italic"> calls #3</SPAN></SPAN>
</PRE>

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

</BLOCKQUOTE>

<BR><BR><HR><A NAME="2359"></A><H4>2359.
  
Unintended copy initialization with designated initializers
</H4><B>Section: </B>11.6.1&#160; [dcl.init.aggr]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Zhihao Yuan
 &#160;&#160;&#160;

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


<P>According to 11.6.1 [dcl.init.aggr] bullet 4.2,</P>

<BLOCKQUOTE>

Otherwise, the element is copy-initialized from the
corresponding <I>initializer-clause</I> or
the <I>brace-or-equal-initializer</I> of the
corresponding <I>designated-initializer-clause</I>.

</BLOCKQUOTE>

<P>This sounds as if the initialization performed by a designated
initializer is always copy-initialization. However, it was intended
that the kind of initialization match the form of the initializer,
i.e., a <I>designated-initializer-clause</I> of the form</P>

<PRE>
  { .x{3} }
</PRE>

<P>was intended to perform direct-initialization.</P>

<P><B>Proposed resolution, April, 2018:</B></P>

<P>Change 11.6.1 [dcl.init.aggr] bullet 4.2 as follows:</P>

<BLOCKQUOTE>

Otherwise, the element is copy-initialized from the
corresponding <I>initializer-clause</I> or <SPAN style="font-weight:bold;background-color:#A0FFA0">is initialized with</SPAN>
the <I>brace-or-equal-initializer</I> of the
corresponding <I>designated-initializer-clause</I>.

</BLOCKQUOTE>

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