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