<html><head><meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>Introducing a name for brace-or-equal-initializers for non-static data members</title>

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

blockquote { color: #000000; background-color: #F1F1F1;
  border: 1px solid #D1D1D1;
  padding-left: 0.5em; padding-right: 0.5em; }
blockquote.stdins { text-decoration: underline;
  color: #000000; background-color: #C8FFC8;
  border: 1px solid #B3EBB3; padding: 0.5em; }
blockquote.stddel { text-decoration: line-through;
  color: #000000; background-color: #FFEBFF;
  border: 1px solid #ECD7EC;
  padding-left: 0.5empadding-right: 0.5em; ; }
</style>

</head>

<body>
<div style="text-align: right; float: right">
ISO/IEC JTC1 SC22 WG21<br>
P0134R0<br>
Richard Smith<br>
richard@metafoo.co.uk<br>
2015-09-23<br>
</div>

<h1>Introducing a name for brace-or-equal-initializers for non-static data members</h1>

N2756 introduced the ability to specify a default initializer for a non-static data member:

<pre>class X {
  int a = 123;
  X() {} // initialize 'a' to 123
};</pre>

However, it did not introduce a useful term into the standard to describe these
entities. This has resulted in a number of terms being in common usage to
describe these initializers:

<ul>
  <li><b>Non-static data member initializers</b>: This is the name of the papers
  introducing the feature. It is also the name used by GCC, where it is frequently
  shortened to "NSDMI" due to its unwieldy length.
  <li><b><i>brace-or-equal-initializer</i> for a non-static data member</b>: This
      is the name used by the standard.
  <li><b>In-class initializers</b></li>
  <li><b>Default member initializers</b></li>
</ul>

As Project Editor, I believe that having a name for this construct is useful for
the presentation of the C++ standard, and that having a single name is useful
for discourse within the C++ community at large. As with the term "forwarding
reference", agreeing on the term within the C++ committee and using the term
within the C++ standard is the best way to get a single term adopted.

<p>Based on many discussions within and outside the committee, this paper proposes
that we use the term <i>default member initializer</i> for this construct. This
term is specific enough to uniquely identify the scenario, reflects the
symmetry between this construct and similar cases (default arguments and default
template arguments, and a constructor's <i>mem-initializer</i>s),
and is terse enough that an abbreviation (such as NSDMI) does not need to be invented.

<h2>Proposed wording</h2>

Change in [expr.prim.general] (5.1.1) paragraph 4:

<blockquote>
Otherwise, if a member-declarator declares a non-static data member (9.2) of a
class X, the expression this is a prvalue of type "pointer to X" within the
optional <del>brace-or-equal-initializer</del><ins>default member initializer</ins>.
It shall not appear elsewhere in the member-declarator.
</blockquote>

Change in [expr.prim.general] (5.1.1) paragraph 5 example:

<blockquote>
<pre>class Outer {
    int a[sizeof(*this)];            // error: not inside a member function
    unsigned int sz = sizeof(*this); // OK: in <del>brace-or-equal-initializer</del><ins>default member initializer</ins>
[...]</pre>
</blockquote>

Change in [dcl.init.aggr] (8.5.1) paragraph 7:

<blockquote>
If there are fewer initializer-clauses in the list than there are members in
the aggregate, then each member not explicitly initialized shall be initialized
from its <del>brace-or-equal-initializer</del><ins>default member initializer (9.2)</ins>
or, if there is no <del>brace-or-equal-initializer</del><ins>default member initializer</ins>,
from an empty initializer list (8.5.4).
</blockquote>

Change in [dcl.init.aggr] (8.5.1) paragraph 8:

<blockquote>
If a reference member is initialized from its
<del>brace-or-equal-initializer</del><ins>default member initializer</ins>
and a potentially-evaluated subexpression thereof is an aggregate
initialization that would use that
<del>brace-or-equal-initializer</del><ins>default member initializer</ins>,
the program is ill-formed. 
</blockquote>

Change in [class.mem] (9.2) paragraph 2:

<blockquote>
Within the class member-specification, the class is regarded as complete within
function bodies, default arguments, using-declarations introducing inheriting
constructors (12.9), exception-specifications, and
<del>brace-or-equal-initializers for non-static data members</del><ins>default member initializers</ins>
(including such things in nested classes)
</blockquote>

Change in [class.mem] (9.2) paragraph 4:

<blockquote>
A brace-or-equal-initializer shall appear only in the declaration of a data
member.
(For static data members, see 9.4.2; for non-static data members, see 12.6.2 <ins>and 8.5.1</ins>).
A brace-or-equal-initializer for a non-static data member
<ins>specifies a <i>default member initializer</i> for the member, and</ins>
shall not directly or
indirectly cause the implicit definition of a defaulted default constructor for
the enclosing class or the exception specification of that constructor.
</blockquote>

Change in [class.union] (9.5) paragraph 8:

<blockquote>
A union-like class is a union or a class that has an anonymous union as a
direct member. A union-like class X has a set of variant members. If X is a
union, a non-static data member of X that is not an anonymous union is a
variant member of X. In addition, a non-static data member of an anonymous
union that is a member of X is also a variant member of X. At most one variant
member of a union may have a <del>brace-or-equal-initializer</del><ins>default member initializer</ins>.
</blockquote>

Change in [class.ctor] (12.1) paragraph 4 bullet 2:

<blockquote>
  <ul><li>any non-static data member with no <del>brace-or-equal-initializer</del><ins>default member initializer</ins> is of reference type,</ul>
</blockquote>

Change in [class.ctor] (12.1) paragraph 4 bullet 9:

<blockquote>
  <ul><li>no non-static data member of its class has a <del>brace-or-equal-initializer</del><ins>default member initializer</ins>, and</ul>
</blockquote>

Change in [class.base.init] (12.6.2) paragraph 9 bullet 1:

<blockquote>
  <ul><li>if the entity is a non-static data member that has a <del>brace-or-equal-initializer</del><ins>default member initializer (9.2)</ins> and either
    <ul><li>
    the constructor's class is a union (9.5), and no other variant member of that union is designated
    by a mem-initializer-id or
    the constructor's class is not a union, and, if the entity is a member of an anonymous union, no other member of that union is designated by a mem-initializer-id,
  </ul>
  the entity is initialized <ins>from its default member initializer</ins> as specified in 8.5;
  </ul>
</blockquote>

Change in [class.base.init] (12.6.2) paragraph 10:

<blockquote>
If a given non-static data member has both a <del>brace-or-equal-initializer</del><ins>default member initializer</ins> and a
mem-initializer, the initialization specified by the mem-initializer is
performed, and the non-static data member's <del>brace-or-equal-initializer</del><ins>default member initializer</ins> is
ignored. [&nbsp;<em>Example</em>: Given
<pre>
  struct A {
  int i = /* some integer expression with side effects */ ; A(int arg) : i(arg) { }
  // ...
  };</pre>
the A(int) constructor will simply initialize i to the value of arg, and the
side effects in i's <del>brace-or-equal-initializer</del><ins>default member
  initializer</ins> will not take place. &mdash;&nbsp;<em>end example</em>&nbsp;]
</blockquote>

Change in [class.base.init] (12.6.2) paragraph 11:

<blockquote>
A temporary expression bound to a reference member from a
<del>brace-or-equal-initializer</del><ins>default member initializer</ins> is
ill-formed.
</blockquote>

Change in [class.base.init] (12.7) paragraph 5:

<blockquote>
[&hellip;] When typeid is used in a constructor (including the mem-initializer or
<del>brace-or-equal-initializer</del><ins>default member initializer</ins> for a non-static data member) or in a destructor,
[&hellip;]
</blockquote>

Change in [class.base.init] (12.7) paragraph 6:

<blockquote>
[&hellip;] When a dynamic_cast is used in a constructor (including the mem-initializer or
<del>brace-or-equal-initializer</del><ins>default member initializer</ins> for a non-static data member) or in a destructor,
[&hellip;]
</blockquote>

Change in [class.copy] (12.8) paragraph 15:

<blockquote>
The implicitly-defined copy/move constructor for a non-union class X performs a
memberwise copy/move of its bases and members. [&nbsp;<em>Note</em>:
<del>brace-or-equal-initializer</del><ins>default member initializer</ins>s of non-static data members are ignored. See also
the example in 12.6.2. &mdash;&nbsp;<em>end note</em>&nbsp;]
</blockquote>

Ensure that an index entry for "default member initializers" is added, pointing
to the definition in [class.mem] (9.2) paragraph 4.

</body></html>
