<html>
<head>
<title>P0683R0: Default member initializers for bit-fields</title>

<style type="text/css">
  ins { text-decoration:none; font-weight:bold; background-color:#A0FFA0 }
  .new { text-decoration:none; font-weight:bold; background-color:#D0FFD0 }
  del { text-decoration:line-through; background-color:#FFA0A0 }  
  strong { font-weight: inherit; color: #2020ff }
  table, td, th { border: 1px solid black; border-collapse:collapse; padding: 5px }
</style>
</head>

<body>
ISO/IEC JTC1 SC22 WG21 P0683R0<br/>
Jens Maurer &lt;Jens.Maurer@gmx.net><br/>
Target audience: EWG and CWG<br/>
2017-06-18<br/>

<h1>P0683R0: Default member initializers for bit-fields</h1>

<h2>Introduction</h2>

<p>

This paper presents wording for the syntax chosen for default member
initializers for bit-fields during the WG21 meeting in Issaquah 2016.
It is a follow-on paper to P0187R1 "Proposal/Wording for Bit-field
Default Member Initializer Syntax" by Andrew Tomazos.
<p>
In a nutshell, the proposal with the most consensus was to support
<pre>
  struct S {
    int x : 5 = 42;
  };
</pre>
with the proviso that parsing ambiguities such as
<pre>
  int a;
  struct S2 {
    int y : true ? 1 : a = 42;
    int z : 1 || new int { 42 };
  };
</pre>
are resolved with a max-munch rule.

<h2>Discussion</h2>

The grammar for the <em>member-declarator</em> of a bit-field (12.2.4 [class.bit]) is
<pre>
  <em>identifier<sub>opt</sub> attribute-specifier-seq<sub>opt</sub> : constant-expression</em>
</pre>

In turn, a <em>constant-expression</em> is
a <em>conditional-expression</em> (see 8.20 [expr.const]), therefore
a <code>=</code> cannot possibly be part of
that <em>constant-expression</em> at the top level.  This makes the
motivating use-case work with a max-munch rule, because parsing of
the <em>constant-expression</em> will stop when the <code>=</code> is
encountered.

<p>
The ambiguous cases shown above are both parsed as
convoluted <em>constant-expression</em>s, so
neither <code>S2::y</code> nor <code>S2::z</code> have a default
member initializer, preserving backward compatibility.  The meaning
can be changed by applying parentheses:

<pre>
  int a;
  struct S2 {
    int y : (true ? 1 : a) = 42;
    int z : (1 || new int) { 42 };
  };
</pre>

<h2>Wording changes</h2>

In 12.2 [class.mem] paragraph 1, change

<blockquote>
<pre>
  <em>member-declarator:
    declarator virt-specifier-seq<sub>opt</sub> pure-specifier<sub>opt</sub>
    declarator brace-or-equal-initializer<sub>opt</sub>
    identifier<sub>opt</sub> attribute-specifier-seq<sub>opt</sub> : constant-expression <ins>brace-or-equal-initializer<sub>opt</sub></ins></em>
</pre>
</blockquote>

Add after 12.2 [class.mem] paragraph 7:

<blockquote>
In a <em>member-declarator</em>, an = immediately following
the <em>declarator</em> is interpreted as introducing
a <em>pure-specifier</em> if the <em>declarator-id</em> has function
type, otherwise it is interpreted as introducing a
<em>brace-or-equal-initializer</em>.  [ Example: ... ]

<p>
<ins>In a <em>member-declarator</em> for a bit-field,
the <em>constant-expression</em> is parsed as the maximum sequence of
tokens that could possibly form a <em>conditional-expression</em>.

[ Example:</ins>
<pre>
<ins>  int a;
  const int b = 0;
  struct S {
    int x : 5 = 42;                 // ok; "= 42" is <em>brace-or-equal-initializer</em>
    int y1 : true ? 1 : a = 42;     // ok; <em>brace-or-equal-initializer</em> is absent
    int y2 : true ? 1 : b = 42;     // error: cannot assign to const int
    int z : 1 || new int { 42 };    // ok; <em>brace-or-equal-initializer</em> is absent
  };</ins>
</pre>
<ins>-- end example ]</ins>
</blockquote>

In 12.2.4 [class.bit] paragraph 1, change

<blockquote>
A <em>member-declarator</em> of the form
<pre>
  <em>identifier<sub>opt</sub> attribute-specifier-seq<sub>opt</sub> : constant-expression <ins>brace-or-equal-initializer<sub>opt</sub></ins></em>
</pre>
specifies a bit-field; its length is set off from the bit-field name
by a colon.
</blockquote>


</body>
</html>
