On Sunday, 29 May 2016 at 14:27:51 UTC, Nick Treleaven wrote:
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(!)

Exactly, and then one of the two suggested approaches will have to be used to prevent the use-after-free. But that's something that needs to happen on assignment, not when the reference is created.


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.

Yes.

I think we should just prevent front from escaping.

It doesn't necessarily need to escape for the problem to occur. Well, it does in this example, but it can be trivially rewritten:

    auto tmp = stdin.byLine;
    auto lines = tmp.array;

Here, `lines` contains references to the buffer owned by `tmp`, but doesn't escape (assuming `array` takes its argument by `scope` or however the final solution will look like).

Reply via email to