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