DIP 1016--ref T accepts r-values--Formal Assessment
kinke
noone at nowhere.com
Thu Jan 24 21:03:29 UTC 2019
On Thursday, 24 January 2019 at 09:04:41 UTC, Nicholas Wilson
wrote:
> On Thursday, 24 January 2019 at 07:18:58 UTC, Mike Parker wrote:
>> The second problem is the use of := (which the DIP Author
>> defines as representing "the initial construction, and not a
>> copy operation as would be expected if this code were written
>> with an = expression"). This approach shows its deficiencies
>> in the multiple arguments case; if the first constructor
>> throws an exception, all remaining values will be destroyed in
>> the void state as they never have the chance to become
>> initialized.
>
> Although not specified by the DIP, I think this could be easily
> remedied by saying that the order of construction is the same
> as if the temporaries were not bound to ref, i.e.
>
> ---
> struct A {~this();} struct B{ ~this();}
> A a();
> B b();
>
> void f(A a, B b);
> void g(ref A a, ref B b);
>
> f(a(),b()); //(1)
> g(a(),b()); //(2)
> ---
>
> and a() or b() may throw (and are pure), that (1) and (2)
> exhibit the same exception/destructor semantics.
Describing this stuff in detail (rewritten expression?!), isn't
trivial and requires knowledge about how calls and
construction/destruction of argument expressions works.
E.g., the f() call in the code above is lowered to (-vcg-ast):
(bool __gate = false;) , ((A __pfx = a();)) , ((B __pfy = b();))
, __gate = true , f(__pfx, __pfy);
Here, (only seemingly unused) temporary `__gate` is used to
control the destruction of temporaries with dtors (here just the
`__pfx` arg, as `__pfy` is a special case [no potentially
throwing later argument expressions...]) at the caller side
(false => destruct; true => skip destruction, as it has been
moved successfully to the callee, which destructed it). The dtor
expressions of these temporaries (e.g., `__gate || __pfx.~this()`
for `__pfx`) aren't visible with `-vg-ast`.
With this DIP, *all* rvalues passed by ref must be lowered to
temporaries. In case they require destruction, the only
difference wrt. the by-value case is that they are *always*
destructed by the caller (after the call, or if an exception is
thrown while they are in scope), i.e., their destruction isn't
controlled by `__gate`.
More information about the Digitalmars-d-announce
mailing list