<html>
<head>
<title>P0507R0: Core Issue 1343: Sequencing of non-class initialization </title>

<style type="text/css">
  ins { text-decoration:none; font-weight:bold; background-color:#A0FFA0 }
  del { text-decoration:line-through; background-color:#FFA0A0 }
  strong { font-weight: inherit; color: #2020ff }
  #xins:checked ~ * ins { display:none; visibility:hidden }
  #xdel:checked ~ * del { display:none; visibility:hidden }
</style>

</head>

<body>
ISO/IEC JTC1 SC22 WG21 P0507R0<br/>
Group: WG21<br/>
Jens Maurer &lt;Jens.Maurer@gmx.net><br/>
2016-11-10<br/>
</p>

<input type="checkbox" id="xins"/><label for="xins">Hide inserted text</label>
<input type="checkbox" id="xdel"/><label for="xdel">Hide deleted text</label>

<h1>P0507R0: Core Issue 1343: Sequencing of non-class initialization </h1>

This paper presents the changes for core issue 1343.  They are presented
as a separate paper due to the volume of the changes.

<p>

Replace 1.9 [intro.execution] paragraph 10 by the following text,
split into separate paragraphs at the editor's discretion:

<blockquote>

<ins>A <em>constituent expression</em> is defined as follows:</ins>

<ul>
<li><ins>The constituent expression of an expression is that
expression.</ins></li>

<li><ins>The constituent expressions of a <em>braced-init-list</em> or of a
(possibly parenthesized) <em>expression-list</em> are the constituent
expressions of the elements of the respective list.</ins></li>

<li><ins>The constituent expressions of a
<em>brace-or-equal-initializer</em> of the form <em>=
initializer-clause</em> are the constituent expressions of the
<em>initializer-clause</em>.</ins></li>

</ul>

<ins>[ Example: </ins>

<pre>
<ins>struct A { int x; };
struct B { int y; struct A a; };
B b = { 5, { 1+1 } };</ins>
</pre>

<ins> The constituent expressions of the <em>initializer</em> used for
the initialization of <code>b</code> are 5 and 1+1. -- end example
]</ins>

<p>

<ins>The <em>immediate subexpression</em>s of an expression
<code>e</code> are</ins>

<ul>
<li><ins>the constituent expressions of <code>e</code>'s operands
(Clause 5),</ins></li>

<li><ins>any function call that <code>e</code> implicitly invokes,</ins></li>

<li><ins>if <code>e</code> is a <em>lambda-expression</em>
(5.1.5 [expr.prim.lambda]), the
initialization of the entities captured by copy and the
constituent expressions of the <em>initializer</em> of the
<em>init-capture</em>s,</ins>

<li><ins>if <code>e</code> is a function call (5.2.2 [expr.call]) or
implicitly invokes a function, the constituent expressions of each
default argument (8.3.6 [dcl.fct.default]) used in the call,
or</ins></li>

<li><ins>if <code>e</code> creates an aggregate object (8.5.1
[dcl.init.aggr]), the constituent expressions of each default member
initializer (9.2 [class.mem]) used in the initialization.</ins></li>

</ul>

<ins>A <em>subexpression</em> of an expression <code>e</code> is an
immediate subexpression of <code>e</code> or a subexpression of an
immediate subexpression of <code>e</code>. [ Note: Expressions
appearing in the <em>compound-statement</em> of a
<em>lambda-expression</em> are not subexpressions of the
<em>lambda-expression</em>. ]</ins>

<p>

A <em>full-expression</em> is

<ul>
  <li><ins>an unevaluated operand (Clause 5 [expr]),</ins></li>

  <li><ins>a <em>constant-expression</em> (5.20 [expr.const]),</ins></li>

<li><ins>an <em>init-declarator</em> (Clause 8 [dcl.decl]) or a
<em>mem-initializer</em> (12.6.2 [class.base.init]), including
the constituent expressions of the initializer,</ins></li>

<li><ins>an invocation of a destructor generated at the end of the
lifetime of an object other than a temporary object (12.2
[class.temporary]), or</ins></li>

<li>an expression that is not a subexpression of another expression <ins>and that is not otherwise part of a
full-expression.</ins></li>

</ul>

<del>[ Note: in some contexts, such as unevaluated operands, a
syntactic subexpression is considered a full-expression (Clause 5). --
end note ]</del> If a language construct is defined to produce an
implicit call of a function, a use of the language construct is
considered to be an expression for the purposes of this
definition. <del>A call to a destructor generated at the end of the
lifetime of an object other than a temporary object is an implicit
full-expression.</del> Conversions applied to the result of an
expression in order to satisfy the requirements of the language
construct in which the expression appears are also considered to be
part of the full-expression.  <ins>For an initializer, performing the
initialization of the entity (including evaluating default
member initializers of an aggregate) is also considered part
of the full-expression.</ins>

[ Example:
<pre>
   struct S {
     S(int i): I(i) { }  <ins>// full-expression is initialization of I</ins>
     int& v() { return I; }
     <ins>~S() noexcept(false) { }</ins>
   private:
     int I;
   };
   S s1(1);              // full-expression is call of S::S(int)
   <ins>void f() {
  </ins>   S s2 = 2;           // full-expression is call of S::S(int)
   <del>void f() {</del>
     if (S(3).v())       // full-expression includes lvalue-to-rvalue and
                         // int to bool conversions, performed before
                         // temporary is deleted at end of full-expression
     { }
     <ins>bool b = noexcept(S());  // exception specification of destructor of S considered for noexcept

     // full-expression is destruction of s2 at end of block</ins>
   }
   <ins>struct B {
      B(S = S(0));
   };
   B b[2] = { B(), B() };   // full-expression is the entire initialization including the destruction of temporaries
</pre>
 -- end example ]

</blockquote>

<p>

Change in 5 [expr] paragraph 8:

<blockquote>
In some contexts, unevaluated operands appear (5.2.8, 5.3.3, 5.3.7,
7.1.6.2). An unevaluated operand is not evaluated.  <del>An
unevaluated operand is considered a full-expression</del>. [ Note: In
an unevaluated operand, a non-static class member may be named (5.1)
and naming of objects or functions does not, by itself, require that a
definition be provided (3.2 [basic.def.odr]).  <ins>An
unevaluated operand is considered a full-expression (1.9
[intro.execution])</ins>.-- end note ] </blockquote>


Change in 7.1.5 [dcl.constexpr] paragraph 9:

<blockquote>    
A <code>constexpr</code> specifier used in an object declaration
declares the object as <code>const</code>. Such an object shall have
literal type and shall be initialized.

<ins>In any <code>constexpr</code> variable declaration, the
full-expression of the initialization shall be a constant
expression (5.20 [expr.const]).</ins>

<del>If it is initialized by a constructor call, that call shall be a
constant expression (5.20 [expr.const]). Otherwise, or if
a <code>constexpr</code> specifier is used in a reference declaration,
every full-expression that appears in its initializer shall be a
constant expression. </del> <del>[ Note: Each implicit conversion used
in converting the initializer expressions and each constructor call
used for the initialization is part of such a full-expression. -- end
note ]</del> [ Example: ...]  </blockquote>


Change in 12.6.2 [class.base.init] paragraph 7:

<blockquote>
[ Example: ... ] <ins>[ Note:</ins> The initialization performed by
each <em>mem-initializer</em> constitutes a full-expression <ins>(1.9
[intro.execution])</ins>. Any expression in a <em>mem-initializer</em>
is evaluated as part of the full-expression that performs the
initialization. <ins>-- end note ]</ins> A <em>mem-initializer</em>
where the <em>mem-initializer-id</em> denotes a virtual base class is
ignored during execution of a constructor of any class that is not the
most derived class.

</blockquote>

Change in 15.4 [except.spec] paragraph 12:

<blockquote>
[...]  <del>A subexpression e1 of an expression e is an <em>immediate
subexpression</em> if there is no subexpression e2 of e such that e1
is a subexpression of e2.</del>

</blockquote>


</body>
</html>
