aliasing expressions and identifiers

Nick Treleaven via Digitalmars-d digitalmars-d at puremagic.com
Sun May 29 07:27:51 PDT 2016


On Friday, 27 May 2016 at 11:50:42 UTC, Marc Schütz wrote:
> On Friday, 27 May 2016 at 10:04:14 UTC, Nick Treleaven wrote:
>> On Thursday, 26 May 2016 at 08:29:41 UTC, Marc Schütz wrote:
>>>
>>> RCArray!int arr = [7];
>>> ref r = arr[0];
>>> arr = [9];        // this releases the old array
>>> r++;              // use after free
...
>> statically prevent the above from compiling using:
>>
>> RCArray(T) {
>>     ...
>>     ref opIndex(size_t) return;
>>
>> Local refs cannot be assigned from a function returning ref if 
>> that function has any parameters marked with the return 
>> attribute. If there is no attribute, local refs + function 
>> returning ref is OK.
>
> Huh? `return` means that the returned reference is owned by the 
> RCArray struct and must therefore not outlive it. If the 
> RCArray is a local variable (or parameter), the local ref is 
> always declared after it (because it must be initialized 
> immediately), and will have a shorter scope than the RCArray. 
> Therefore, such an assignment is always accepted.

What about if the RCArray (of ref count 1) is assigned to a 
different one after the local ref is initialised? That is what 
we're discussing -it's your example above(!)

>>> 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)
>>
>> I don't see directly how this affects byLine.front, that does 
>> not return a reference.
>
> It returns a reference in the wider sense, namely a slice to a 
> private buffer that gets overwritten by each call to `byLine`. 
> Currently, DIP25 only applies to `ref`s in the narrow sense, 
> but I'm assuming it will be generalized to include pointer, 
> slices, class references, AAs and hidden context pointers.
>
> Making the ByLine range constant as long as there's a reference 
> to its buffer would prevent surprises like this:
>
>     auto lines = stdin.byLine.array;
>     // => all elements of `lines` are the same, should have 
> used `byLineCopy`

So your solution would statically prevent popFront because front 
has escaped. I think we should just prevent front from escaping.




More information about the Digitalmars-d mailing list