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

Reply via email to