Am 08.07.2012 22:03, schrieb Richard Smith: > On Sun, Jul 8, 2012 at 12:18 PM, Johannes Schaub > <[email protected] > <mailto:[email protected]>> wrote: > > > > Am 08.07.2012 20:30, schrieb Richard Smith: > > On Sun, Jul 8, 2012 at 6:41 AM, Johannes Schaub > <schaub.johannes-gM/[email protected] > <mailto:ye1e23mwn%[email protected]> > > <mailto:schaub.johannes-gM > <mailto:schaub.johannes-gM>/[email protected].__org > <mailto:ye1e23mwn%[email protected]>>> > wrote: > > > > Am 05.07.2012 10:39, schrieb Richard Smith: > > Author: rsmith > Date: Thu Jul 5 03:39:21 2012 > New Revision: 159733 > > URL: > http://llvm.org/viewvc/llvm-____project?rev=159733&view=rev > <http://llvm.org/viewvc/llvm-__project?rev=159733&view=rev> > > > <http://llvm.org/viewvc/llvm-__project?rev=159733&view=rev > <http://llvm.org/viewvc/llvm-project?rev=159733&view=rev>> > Log: > PR13273: When performing list-initialization with an empty > initializer list, > actually perform value initialization rather than > trying to fake > it with a call > to the default constructor. Fixes various bugs related > to the > previously-missing > zero-initialization in this case. > > I've also moved this and the other list initialization > 'special > case' from > TryConstructorInitialization into TryListInitialization > where > they belong. > > ... > > +namespace explicit_default { > + struct A { > + explicit A(); // expected-note{{here}} > + }; > + A a {}; // ok > + // This is copy-list-initialization, and we choose an > explicit constructor > + // (even though we do so via value-initialization), > so the > initialization is > + // ill-formed. > + A b = {}; // expected-error{{chosen constructor is > explicit}} > +} > + > > > 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? > > > Here's my reading of the standard: > > 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. > > 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- > 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. > > > 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. > > 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. > > They fixed that by modifying 13.3.1.7 instead of introducing a new > bullet in 13.3.3.1.5. See > http://www.open-std.org/jtc1/__sc22/wg21/docs/cwg_defects.__html#1229 > <http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1229> > > > What about this case, then: > > struct S { explicit S(); }; > void f(S); > void g() { f({}); } > > 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. >
I agree that this doesn't quite match my expectation. IMO that is disturbing. > 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". > > > T could have multiple default constructors, so it seems to me that > overload resolution is implied by this. > Honestly I don't know. We have no overload resolution context in clause 13 for such a thing when the call happens entirely implicitly by default initialization, so I assumed that no OR happens and the consequence is just "if there are more than one default constructors, it's ill-formed". But now it's entirely unclear to me what that means for templated constructors, so I guess that somehow one is supposed to assume that there is a function call with the function call syntax or something. Note that prior to C++11, a constructor template could not be able to be called as a default constructor, so in C++03, this wasn't an issue. In C++11 we got function template default arguments and function parameter packs that make it possible. > 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). > > > 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 :) > I think I agree. _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
