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

kinke noone at nowhere.com
Fri Jan 25 23:08:52 UTC 2019


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:

{
   bool __gate = false;
   A __pfx = a();
   try {
     B __pfy = b(); // may throw
     __gate = true;
     return f(__pfx, __pfy); // move args to callee
   } finally {
     __gate || __pfx.__xdtor(); // only destruct if not moved to 
callee
   }
}

With this DIP, the g() call (both rvalue args passed by ref) 
would now become:

{
   A __pfx = a();
   try {
     B __pfy = b(); // may throw
     try {
       return g(__pfx, __pfy); // pass by ref
     } finally {
       __pfy.__xdtor(); // always destructed by caller
     }
   } finally {
     __pfx.__xdtor();
   }
}


More information about the Digitalmars-d-announce mailing list