aliasing expressions and identifiers

Marc Schütz via Digitalmars-d digitalmars-d at puremagic.com
Thu May 26 01:29:41 PDT 2016


On Wednesday, 25 May 2016 at 19:47:06 UTC, Nick Treleaven wrote:
> On 24/05/2016 14:48, Nick Treleaven wrote:
>> What about:
>>
>> @safe unittest
>> {
>>      RCArray!int arr;
> +      arr.length = 1;
>>      ref r = arr[0];
>>      arr.destroy; // refcount drops to zero, arr.impl memory 
>> freed
>>      r++; // writes to unallocated memory
>> }
>
> Here I think local refs must be prevented from initialization 
> by return ref (-dip25). The @rc DIP and RCArray would use 
> return ref. It would be OK to initialize a local ref with a ref 
> function result that is not return ref. Naturally, this would 
> be @safe:
>
> auto slice = [7];
> ref r = slice[0];
> slice.destroy;
> r++; // slice memory still allocated

To elaborate: neither `scope` nor reference counting can ever 
protect you against explicit premature destruction of a 
still-referenced owner. But there is a slightly different 
problematic scenario:

RCArray!int arr = [7];
ref r = arr[0];
arr = [9];        // this releases the old array
r++;              // use after free

But this issue exists even without locale `ref`s:

void foo() {
     RCArray!int arr = [7];
     bar(arr, arr[0]);
}

void bar(ref RCArray!int arr, ref int r) {
     arr = [9];    // this releases the old array
     r++;          // use after free
}

It can be solved in one of two ways: Either by making the owner 
(`arr`) non-mutable during the existence of the references, 
thereby forbidding the call to `bar()` (I would prefer this one, 
as it's cleaner and can be used for many more things, e.g. the 
byLine problem), or by making the owner live longer by inserting 
the appropriate AddRef/Release pairs whenever such a situation 
arises.


More information about the Digitalmars-d mailing list