<div class="gmail_quote">On Sun, Jul 8, 2012 at 6:41 AM, Johannes Schaub <span dir="ltr"><<a href="mailto:schaub.johannes@googlemail.com" target="_blank">schaub.johannes@googlemail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<br>
<br>
Am 05.07.2012 10:39, schrieb Richard Smith:<div><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Author: rsmith<br>
Date: Thu Jul  5 03:39:21 2012<br>
New Revision: 159733<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=159733&view=rev" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project?rev=159733&view=rev</a><br>
Log:<br>
PR13273: When performing list-initialization with an empty initializer list,<br>
actually perform value initialization rather than trying to fake it with a call<br>
to the default constructor. Fixes various bugs related to the previously-missing<br>
zero-initialization in this case.<br>
<br>
I've also moved this and the other list initialization 'special case' from<br>
TryConstructorInitialization into TryListInitialization where they belong.<br>
<br>
</blockquote></div>
...<div><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+namespace explicit_default {<br>
+  struct A {<br>
+    explicit A(); // expected-note{{here}}<br>
+  };<br>
+  A a {}; // ok<br>
+  // This is copy-list-initialization, and we choose an explicit constructor<br>
+  // (even though we do so via value-initialization), so the initialization is<br>
+  // ill-formed.<br>
+  A b = {}; // expected-error{{chosen constructor is explicit}}<br>
+}<br>
+<br>
</blockquote>
<br></div>
Richard, I'm pretty sure that this is valid code. A value-initialization doesn't respect "explicit". Are you assuming a C++ Standard defect here?<br></blockquote><div><br></div><div>Here's my reading of the standard:</div>

<div><br></div><div>By 8.5.4/1, this is copy-list-initialization. By 8.5.4/3, the object is value-initialized. By 8.5/7, "the default constructor for T is called". That's all normal.</div><div><br></div><div>
Now, the question is, does 13.3.1.7 apply when choosing the default constructor to call, in the case where T has a default constructor and so list-initialization delegates to value-initialization? If so, "In copy-list-</div>
<div>initialization, if an explicit constructor is chosen, the initialization is ill-formed." And I think 13.3.1.7 is actually pretty clearly intended to apply to this case, because it says "If the initializer list has no elements and T has a default constructor, the first phase is omitted." So I think the standard is clear here that this should be ill-formed.</div>
<div><br></div><div>That said, maybe this isn't what was intended, and if so, I think we have a defect. I do find this disturbing:</div><div><br></div><div>struct A {</div><div>  explicit A() = default;</div><div>};</div>
<div>A a = {}; // ok in N3337, aggregate initialization (error in FDIS)</div><div>struct B : A {</div><div>  explicit B() = default;</div><div>};</div><div>B b = {}; // ok, trivial and not user-provided</div><div>struct C {</div>
<div>  explicit C();</div><div>};</div><div>C c = {}; // error, default ctor called because it is user-provided</div><div>struct D : A {</div><div>  C c;</div><div>  explicit D() = default;</div><div>};</div><div>D d = {}; // error, default ctor called because it is non-trivial</div>
<div><br></div><div>Note that CWG issue 1301 (voted into the WP at Kona) resolved that aggregate initialization beats value-initialization, so A is valid and clang accepts it. We reject C and D correctly, but incorrectly reject B, because we don't model that the constructor is sometimes not actually called by value-initialization.</div>
</div>