<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
	<title>Initializers of objects with automatic and dynamic storage duration have funny inconsistencies</title>

	<style>
	p {text-align:justify}
	li {text-align:justify}
	blockquote.note
	{
		background-color:#E0E0E0;
		padding-left: 15px;
		padding-right: 15px;
		padding-top: 1px;
		padding-bottom: 1px;
	}
	ins {color:#00A000}
	del {color:#A00000}
	</style>
</head>
<body>

<address align=right>
Document number: P0965R0
<br/>
Audience: EWG
<br/>
<br/>
<a href="mailto:ville.voutilainen@gmail.com">Ville Voutilainen</a><br/>
2018-02-12<br/>
</address>
<hr/>
<h1 align=center>Initializers of objects with automatic and dynamic storage duration have funny inconsistencies</h1>

<h2>Abstract</h2>
<p>
  This paper talks about the differences of initializers of objects with automatic vs. dynamic storage duration; in particular, the difference
  of initializing an object of a type vs. initializing a pointer to that
  type with a new-expression. See the thread starting
  at <a href=http://lists.isocpp.org/ext/2017/12/3419.php>http://lists.isocpp.org/ext/2017/12/3419.php</a>.
</p>
<p>
  The gist of the problem is that these are different:
</p>
<p>
  <pre>
    <code>
      double* p = new double[]{1,2,3}; // not ok
      double a[] {1,2,3}; // ok
    </code>
  </pre>
</p>
<p>
  A different inconsistency:
</p>
<p>
  <pre>
    <code>
      double** pp = new double*{nullptr};   // ok
      double* p = double*{nullptr};   // not ok
    </code>
  </pre>
</p>

<h2>The issue explained</h2>

<p>
  An innocent user might expect that if you can write T x{something};,
  you could also write T* x = new T{something};, and vice versa. In both
  of the examples in the abstract, that is not the case:
  <ul>
    <li>For the first example, the straightforward array variable declaration is ok, but the pointer initialized by new is not, because new requires the expression in the brackets</li>
    <li>For the second example, as Timur Doumler explains it in the mailing
      list thread, "in a new-declarator the * is always parsed as part of the type - in a regular initialiser it's instead parsed as part of an expression."</li>
  </ul>
</p>
<p>
  The second example may be beyond fixing. Making the * be part of the
  type rather than part of the expression is certainly a breaking change.
</p>
</body>

<p>
  For the first example, Jens Maurer provided an explanation why it doesn't work:
</p>
<p>
  <blockquote>
  <pre>
Level 1 answer:

Because the expression inside the square brackets is mandatory
for a new-expression; see 8.5.2.4 [expr.new] p1.
That situation is unchanged since at least C++03.

Level 2 answer:

When braced-init-lists were added to /new-initializer/ in the
course of uniform initialization, the rule about deducing the
size of the array from the number of initializers was never
extended to the new-expression case.

Level 3 answer:

I don't know of a fundamental reason why we can't make this
work.  Papers welcome.
  </pre>
  </blockquote>
</p>

<p>
  It seems to me that a combination of adding deduction to a new-expression
  and then removing the requirement for the expression inside square
  brackets should fix the problem in the first example.
</p>

<h2>A more detailed solution</h2>

<p>
  Hey, I just wrote this paper so that we can talk about the issue,
  the actual technical solution is left as an exercise for readers. :)
</p>

</html>
