C++ Logo

std-proposals

Advanced search

Re: Fixing some initialization gotchas

From: Ville Voutilainen <ville.voutilainen_at_[hidden]>
Date: Fri, 23 Aug 2019 17:36:19 +0300
On Fri, 23 Aug 2019 at 17:22, Maciej Cencora via Std-Proposals
<std-proposals_at_[hidden]> wrote:
>
> Yes, I am proposing to make 'auto x{1};' ill formed because such form is ambiguous depending on how many elements you pass in braced init list (and it differs in C++11).

You can't pass multiple elements to that form.

> Fixing the fall-out is trivial (either use 'auto x = 1;' or 'std::initializer_list x = { 1 };') and compatible with C++17.
> Isn't simplification of initialization rules a good enough argument?

It's questionable whether that simplifies the rules.

> Aah, I forgot to write, I propose to unify direct-init and copy-init as well:
> T a = b;
> T a(b);
>
> In C++17 these will do exactly the same thing (minus explicit constructor).

And that difference of whether it can call an explicit constructor was
deemed important when
http://open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4014.pdf was rejected.
>
> As for the cases where you may get a silent change w.r.t. explicit vs non explicit constructor, I believe there is only one:
> struct A
> {
> explicit A(int);
> A(double);
> };
>
> A a = 1;
> I would be surprised if user actually expected the non-explicit constructor to be called in such scenario.
>
> For other cases, you will get compiler error do to ambiguity:
> struct A
> {
> explicit A(short);
> A(double);
> };
>
> A a = 1;
> Which again is a good thing, because it is not really clear what user meant in the first place.
> And again fixing such fallout is simple (either you use 'A a(short(1));' or 'A a(double(1));') and you still stay compatible with previous C++ versions.
>
> Regards,
> Maciej
>
>
> pt., 23 sie 2019 o 13:49 Timur Doumler <cpp_at_[hidden]> napisał(a):
>>
>> IIUC, you are proposing to make existing code like auto x{1}; ill-formed that is well-formed today.
>>
>> Further, you are proposing to silently change the behaviour of existing code. Imagine a class with an explicit c’tor and a non explicit one: your proposal might silently change which c’tor gets called.
>>
>> When proposing such breakage, you should really have a good argument why that’s worth it, and study how much real-world code would actually be affected. How many such initailisations per MLoC exist in existing large code bases?
>>
>> Further, the distinction between direct-list-init and copy-list-init has parallels with the much older distinction between direct-init and copy-init. You would be breaking that consistency on a conceptual level.
>>
>> Timur
>>
>> On 23 Aug 2019, at 11:40, Maciej Cencora via Std-Proposals <std-proposals_at_[hidden]> wrote:
>>
>> Yes, I have seen it and it was one of motivations to write this proposal.
>>
>> pt., 23 sie 2019 o 11:15 Eyal Rozenberg <eyalroz_at_[hidden]> napisał(a):
>>>
>>> Have you seen Nikolai Josuttis's talk, “The Nightmare of Initialization
>>> in C++”
>>> https://www.youtube.com/watch?v=7DTlWPgX6zs
>>> ?
>>>
>>> If not, give it a watch; I remember it presents all sorts of eccentric
>>> use case and rationales. Josuttis says that he ends up in a state where
>>> he is not sure what exactly needs to be "fixed". That would give you
>>> perspective on your proposal (and perhaps shoot it down - I'm not sure.)
>>>
>>> Eyal
>>>
>>> On 23/08/2019 11:01, Maciej Cencora via Std-Proposals wrote:
>>> > If it is already, then yes, and removing the explicit constructor
>>> > requirement for copy-list initialization in return statement won't
>>> > change that.
>>> >
>>> > Anyway the main point of this proposal is to unify initialization
>>> > behavior a little more in context of variable/member declaration, so
>>> > changing explicit constructor requirement in this case could be dropped
>>> > if LEWG has strong objections.
>>> >
>>> > So what do you think?
>>> >
>>> >
>>> >
>>> >
>>> >
>>> > pt., 23 sie 2019 o 01:05 Tony V E <tvaneerd_at_[hidden]
>>> > <mailto:tvaneerd_at_[hidden]>> napisał(a):
>>> >
>>> > I think there was a convincing examples from Howard Hinnant like
>>> >
>>> > chrono::seconds f()
>>> > {
>>> > Long();
>>> > Function();
>>> > ...
>>> > if (condition)
>>> > return i;
>>> >
>>> > Morestuff();
>>> > Etc();
>>> >
>>> > return chrono::minutes(j);
>>> > }
>>> >
>>> > Is that function correct?
>>> >
>>> > Sent from my BlackBerry portable Babbage Device
>>> > *From: *Maciej Cencora
>>> > *Sent: *Thursday, August 22, 2019 4:56 PM
>>> > *To: *Tony V E
>>> > *Cc: *sotrdg sotrdg via Std-Proposals
>>> > *Subject: *Re: [std-proposals] Fixing some initialization gotchas
>>> >
>>> >
>>> > And what were LEWG arguments for saying no here?
>>> >
>>> > czw., 22 sie 2019 o 22:55 Tony V E <tvaneerd_at_[hidden]
>>> > <mailto:tvaneerd_at_[hidden]>> napisał(a):
>>> >
>>> >
>>> >
>>> > On Thu, Aug 22, 2019 at 4:46 PM Maciej Cencora via Std-Proposals
>>> > <std-proposals_at_[hidden]
>>> > <mailto:std-proposals_at_[hidden]>> wrote:
>>> >
>>> > Yes.
>>> >
>>> > After all you are explicit about the return type of the
>>> > function (you specified it in function definition), so why
>>> > would you not want this to work? There is no possibility for
>>> > amibiguity here.
>>> >
>>> > czw., 22 sie 2019 o 22:36 sdkrystian via Std-Proposals
>>> > <std-proposals_at_[hidden]
>>> > <mailto:std-proposals_at_[hidden]>> napisał(a):
>>> >
>>> > So you propose that this should be well formed?
>>> >
>>> > struct S { explicit operator int() { return 42; } };
>>> >
>>> > int f()
>>> > {
>>> > return { S() };
>>> > }
>>> >
>>> >
>>> > Having explicit work here has been voted on by the committee in
>>> > the past, and LEWG strongly said No.
>>> >
>>> >
>>> > --
>>> > Be seeing you,
>>> > Tony
>>> >
>>> >
>>> >
>>
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>
>>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals

Received on 2019-08-23 09:38:34