Lifetime tracking

Marc Schütz via Digitalmars-d digitalmars-d at puremagic.com
Mon Jun 6 10:52:34 PDT 2016


On Thursday, 2 June 2016 at 23:29:57 UTC, Timon Gehr wrote:

>
> void foo(scope int* k){
>     void bar(){
>         scope int* x;
>         // need to check that lifetime of x ends not after 
> lifetime of k
>         assign(x,k);
>     }
> }
>
> I.e. now we need a way to annotate 'assign' in order to specify 
> the contract I have written down in the comments.
> ...
> [1] It might be possible to get that example to pass the type 
> checker with 'return' annotations only if I change 'ref' to 
> 'out',

There needs to be additional syntax for specifying that an input 
reference escapes through another parameter, not through 
returning. For example:

void assign(S, T)(ref S a, T b return!a) {
     a = b;    // accepted, as specified in the signature
}

void foo(scope int* k) {
     void bar() {
         scope int* x;
         assign(x, k);  // accepted, because L(x) < L(k)
     }
}

(By the way, both the `return` annotation in `assign()` and the 
`scope` in the declaration of `x` don't need to be explicit, they 
can inferred because `assign()` is a template and `x` is a local 
variable.)

But AFAICS, the point about `out` vs `ref` isn't correct. `out` 
resets the parameter to its `.init` value. The specification 
currently doesn't say whether this is done by assignment or by 
destruction followed by blitting, but in any case, both 
`opAssign()` and `~this()` have access to the original reference; 
therefore using `out` doesn't help in the general case (not an 
issue for POD types, though).

> but often more than two lifetimes are involved, and then it 
> falls flat on its face.

Can you expand on that? With the addition of a provision for 
escaping by reference as suggested (and maybe for escaping by a 
global variable/heap), the `return` syntax should be able to 
express all lifetime relations that don't go more than one 
indirection deep.


More information about the Digitalmars-d mailing list