[cfe-commits] r159733 - in /cfe/trunk: lib/Sema/SemaInit.cpp test/CodeGenCXX/const-init-cxx11.cpp test/CodeGenCXX/constructor-init.cpp test/SemaCXX/constant-expression-cxx11.cpp test/SemaCXX/cxx0x-initializer-constructor.cpp
Johannes Schaub
schaub.johannes at googlemail.com
Sun Jul 8 13:42:48 PDT 2012
Am 08.07.2012 22:03, schrieb Richard Smith:
> On Sun, Jul 8, 2012 at 12:18 PM, Johannes Schaub
> <schaub.johannes at googlemail.com
> <mailto:schaub.johannes at googlemail.com>> wrote:
>
>
>
> Am 08.07.2012 20:30, schrieb Richard Smith:
>
> On Sun, Jul 8, 2012 at 6:41 AM, Johannes Schaub
> <schaub.johannes-gM/Ye1E23mwN+__BqQ9rBEUg at public.gmane.org
> <mailto:Ye1E23mwN%2BBqQ9rBEUg at public.gmane.org>
>
> <mailto:schaub.johannes-gM
> <mailto:schaub.johannes-gM>/Ye1__E23mwN+BqQ9rBEUg at public.gmane.__org
> <mailto:Ye1E23mwN%2BBqQ9rBEUg at public.gmane.org>>>
> 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.
More information about the cfe-commits
mailing list