DIP25/DIP1000: My thoughts round 2

Chris M. chrismohrfeld at comcast.net
Fri Sep 7 01:00:24 UTC 2018


On Sunday, 2 September 2018 at 05:14:58 UTC, Chris M. wrote:

> Hopefully that was coherent. Again this is me for me to get my 
> thoughts out there, but also I'm interested in what other 
> people think about this.

Somewhat related, I was reading through this thread on why we 
can't do ref variables and thought this was interesting. A lot of 
these use cases could be prevented. I tacked my own comments on 
with //**

https://forum.dlang.org/post/aqvtunmdqfkrsvzlgcet@forum.dlang.org

struct S {
     return ref int r;
}

//ref local variable/stack, Ticking timebomb
//compiler may refuse
//** nope, never accept this
void useRef(ref S input, int r) {
     input.r = r; //** error
}

//should be good, right?
S useRef2(S input, return ref int r) {  //Can declare @safe, 
right???
     input.r = r; //maybe, maybe not.
                  //** sure we can
     return S;
}

//Shy should indirect care if it's local/stack or heap?
//** someone double-check my rationale here, but it should be fine
S indirect(return ref int r) {
     return useRef2(S(), r);
}

//local variables completely okay to ref! Right?
//** Nope! Reject! indirect2() knows whatever receives the return 
value can't outlive r
S indirect2() {
     int r;
     return useRef2(S(), r);
}

S someScope() {
     int* pointer = new int(31); //i think that's right
     int local = 127;

     S s;

     //reference to calling stack! (which may be destroyed now);
     //Or worse it may silently work for a while
     //** or the function never gets compiled
     useRef(s, 99);
     assert(s.r == 99);
     return s;

     s = useRef2(s, pointer); //or is it *pointer?
                              //** no clue what to say about this 
one
     assert(s.r == 31); //good so far if it passes correctly
     return s; //good, heap allocated

     s = useRef2(s, local); //** fine here, local outlives s
     assert(s.r == 127); //good so far (still local)
     return s; //Ticking timebomb!
               //** but we reject it here

     s = indirect(local); //** fine here, local outlives s
     assert(s.r == 127); //good so far (still local)
     return s; //timebomb!
               //** reject again

     s = indirect2(); //** never accepted in the first place
     return s; //already destroyed! Unknown consequences!
}


More information about the Digitalmars-d mailing list