<div class="gmail_quote">On Sun, Jul 8, 2012 at 12:18 PM, 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 08.07.2012 20:30, schrieb Richard Smith:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">
On Sun, Jul 8, 2012 at 6:41 AM, Johannes Schaub<br></div>
<schaub.johannes-gM/<a href="mailto:Ye1E23mwN%2BBqQ9rBEUg@public.gmane.org" target="_blank">Ye1E23mwN+<u></u>BqQ9rBEUg@public.gmane.org</a><div class="im"><br>
<mailto:<a href="mailto:schaub.johannes-gM" target="_blank">schaub.johannes-gM</a>/<a href="mailto:Ye1E23mwN%2BBqQ9rBEUg@public.gmane.org" target="_blank">Ye1<u></u>E23mwN+BqQ9rBEUg@public.gmane.<u></u>org</a>>> wrote:<br>

<br>
<br>
<br>
    Am 05.07.2012 10:39, schrieb Richard Smith:<br>
<br>
        Author: rsmith<br>
        Date: Thu Jul  5 03:39:21 2012<br>
        New Revision: 159733<br>
<br></div>
        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><div><div class="h5"><br>
        <<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<br>
        initializer list,<br>
        actually perform value initialization rather than trying to fake<br>
        it with a call<br>
        to the default constructor. Fixes various bugs related to the<br>
        previously-missing<br>
        zero-initialization in this case.<br>
<br>
        I've also moved this and the other list initialization 'special<br>
        case' from<br>
        TryConstructorInitialization into TryListInitialization where<br>
        they belong.<br>
<br>
    ...<br>
<br>
        +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<br>
        explicit constructor<br>
        +  // (even though we do so via value-initialization), so the<br>
        initialization is<br>
        +  // ill-formed.<br>
        +  A b = {}; // expected-error{{chosen constructor is explicit}}<br>
        +}<br>
        +<br>
<br>
<br>
    Richard, I'm pretty sure that this is valid code. A<br>
    value-initialization doesn't respect "explicit". Are you assuming a<br>
    C++ Standard defect here?<br>
<br>
<br>
Here's my reading of the standard:<br>
<br>
By 8.5.4/1, this is copy-list-initialization. By 8.5.4/3, the object is<br>
value-initialized. By 8.5/7, "the default constructor for T is called".<br>
That's all normal.<br>
<br>
Now, the question is, does 13.3.1.7 apply when choosing the default<br>
constructor to call, in the case where T has a default constructor and<br>
so list-initialization delegates to value-initialization? If so, "In<br>
copy-list-<br>
initialization, if an explicit constructor is chosen, the initialization<br>
is ill-formed." And I think 13.3.1.7 is actually pretty clearly intended<br>
to apply to this case, because it says "If the initializer list has no<br>
elements and T has a default constructor, the first phase is omitted." So<br>
I think the standard is clear here that this should be ill-formed.<br>
<br>
</div></div></blockquote>
<br>
The special casing of default constructors at 13.3.1.7 was not intended to make calls of explicit default constructors during value initialization ill-formed.<br>
<br>
It was intended to harmonize clause 13 with clause 8, because clause 13 directly invokes 13.3.1.7 from 13.3.3.1.5 instead of special casing default constructors at that place.<br>
<br>
They fixed that by modifying 13.3.1.7 instead of introducing a new bullet in 13.3.3.1.5. See <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1229" target="_blank">http://www.open-std.org/jtc1/<u></u>sc22/wg21/docs/cwg_defects.<u></u>html#1229</a></blockquote>
<div><br></div><div>What about this case, then:</div><div><br></div><div>struct S { explicit S(); };</div><div>void f(S);</div><div>void g() { f({}); }</div><div><br></div><div>Here, we do take the 13.3.3.1.5 route into 13.3.1.7. As with the other form, g++ accepts the above, clang rejects it -- I think you are suggesting that in this case clang is right, and in the other case, g++ is right? It would seem surprising to me if this is intended to behave so differently from other cases of copy-list-initialization from an empty initializer list.</div>
<div><br></div><div>My approach fares slightly better, but still has a surprise: with the classes from my prior email, the above is legal under my interpretation if S is replaced by A (because it's an aggregate), but ill-formed for B, C, and D. The trivial default constructor exemption does not apply for B in this case, because 13.3.3.1.5 doesn't mention it.</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Regarding 8.5.4/3, it doesn't necessarily state that overload resolution is done. It simply says the "default constructor of T is called".<br></blockquote><div><br></div><div>T could have multiple default constructors, so it seems to me that overload resolution is implied by this.</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
The way that DR1229 was fixed however makes this thing way less clear than I initially felt it is, so I will partially agree with you that clang's trunk position is not all that bad, but I still feel like this should be talked with core (GCC does not implement it like this, for one).<br>

</blockquote></div><br><div>g++ doesn't follow (my understanding of) your approach either, based on the example above. I definitely think we have enough confusion here to warrant a core issue :)</div>