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.