DIP 1016--ref T accepts r-values--Formal Assessment

Neia Neutuladh neia at ikeran.org
Sat Jan 26 00:17:29 UTC 2019


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();
        }
    }
}


More information about the Digitalmars-d-announce mailing list