`return ref`, DIP25, and struct/class lifetimes

Dicebot via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon May 16 08:33:09 PDT 2016


tl; dr: DIP25 is so heavily under-implemented in its current 
shape it can be considered 100% broken and experimenting will 
uncover even more glaring holes.

To be more precise, judging by experimental observation, 
currently dip25 only works when there is explicitly a `ref` 
return value in function or method. Any escaping of reference 
into a pointer confuses it completely:

ref int wrap ( return ref int input )
{
     return input;
}

ref int badWrapper()
{
     int x = 5;
     return wrap(x); // Error: escaping reference to local 
variable x
}

void main()
{
     auto badWrap = badWrapper();
}

vs

struct S
{
     int* ptr;
}

S wrap ( return ref int input )
{
     return S(&input);
}

S badWrapper()
{
     int x = 5;
     return wrap(x); // OK!
}

void main()
{
     auto badWrap = badWrapper();
}

vs

struct S
{
     int* ptr;
}

ref S wrap ( return ref int input )
{
     static S tmp; // spot another hole :)
     tmp = S(&input);
     return tmp;
}

ref S badWrapper()
{
     int x = 5;
     return wrap(x); // Error: escaping reference to local 
variable x
}

void main()
{
     auto badWrap = badWrapper();
}

You can probably spot the pattern here - compiler matches `return 
ref` in parameter declaration to `ref` in return value and 
enforces identical lifetime for those. No `ref` in return value - 
no enforcing, but it will also happily accept nonsense `return 
ref` annotations.

Theoretically it was supposed to be protected by `@safe` 
attribute as one can't take address of local variable in safe 
code. But there isn't any way to write such wrapper struct 
without using pointers AFAIK.

In your actual example putting `return` on `get` method 
annotation is additionally very misleading because it only 
implies ensuring result does not outlive struct instance itself - 
but it gets passed around by value anyway.


More information about the Digitalmars-d-learn mailing list