DIP 1016--ref T accepts r-values--Formal Assessment
Manu
turkeyman at gmail.com
Sat Jan 26 02:14:56 UTC 2019
On Fri, Jan 25, 2019 at 4:20 PM Neia Neutuladh via
Digitalmars-d-announce <digitalmars-d-announce at puremagic.com> wrote:
>
> On Fri, 25 Jan 2019 23:08:52 +0000, kinke wrote:
>
> > On Friday, 25 January 2019 at 19:08:55 UTC, Walter Bright wrote:
> >> On 1/25/2019 2:57 AM, kinke wrote:
> >>> On Thursday, 24 January 2019 at 23:59:30 UTC, Walter Bright wrote:
> >>>> On 1/24/2019 1:03 PM, kinke wrote:
> >>>>> (bool __gate = false;) , ((A __pfx = a();)) , ((B __pfy =
> >>>>> b();)) , __gate = true , f(__pfx, __pfy);
> >>>>
> >>>> There must be an individual gate for each of __pfx and pfy.
> >>>> With the rewrite above, if b() throws then _pfx won't be destructed.
> >>>
> >>> There is no individual gate, there's just one to rule the
> >>> caller-destruction of all temporaries.
> >>
> >> What happens, then, when b() throws?
> >
> > `__pfx` goes out of scope, and is dtor expression (cleanup/finally) is
> > run as part of stack unwinding. Rewritten as block statement:
>
> And nested calls are serialized as you'd expect:
>
> int foo(ref S i, ref S j);
> S bar(ref S i, ref S j);
> S someRvalue(int i);
>
> foo(
> bar(someRvalue(1), someRvalue(2)),
> someRvalue(4));
>
> // translates to something like:
> {
> bool __gate1 = false;
> S __tmp1 = void;
> S __tmp2 = void;
> S __tmp3 = void;
> __tmp1 = someRvalue(1);
> try
> {
> __tmp2 = someRvalue(2);
> __gate1 = true;
> __tmp3 = bar(__tmp1, __tmp2);
> }
> finally
> {
> if (!__gate1) __tmp1.__xdtor();
> }
> S __tmp4 = void;
> bool __gate2 = false;
> try
> {
> __tmp4 = someRvalue(4);
> __gate2 = true;
> return foo(__tmp3, __tmp4);
> }
> finally
> {
> if (!__gate2)
> {
> __tmp3.__xdtor();
> }
> }
> }
Is this fine?
Given above example:
int foo(ref S i, ref S j);
S bar(ref S i, ref S j);
S someRvalue(int i);
foo(
bar(someRvalue(1), someRvalue(2)),
someRvalue(4));
===>
{
S __tmp0 = someRvalue(1);
S __tmp1 = someRvalue(2);
S __tmp2 = bar(__tmp0, __tmp1);
S __tmp3 = someRvalue(4);
foo(__tmp2, __tmp3);
}
Removing the `void` stuff end expanding such that the declaration +
initialisation is at the appropriate moments; any function can throw
normally, and the unwind works naturally?
More information about the Digitalmars-d-announce
mailing list