Brad Roberts wrote:
Walter Bright wrote:
Brad Roberts wrote:
Yay.  What will happen with slices over a T[new] when the underlying
T[new] must
be moved due to resizing?  The behavior needs to be at least well
specified, if
not well defined.
Great question! It's no different from what happens with any container
when its contents change and there are references to the old content.

What won't happen is the slice won't be pointing to unallocated memory,
thanks to the gc. Resizing the T[new] will not cause the old contents to
be deleted.

The slice will either point to the old content, if the resize caused a
move, or the new content, if it was resized in place. So it will still
be implementation-defined behavior.

But the likelihood of getting caught by such behavior is much less
likely with T[new], as one can clearly see in the code where the
resizeables are, rather than the current situation where any slice could
be resized by anyone.

I think that taking a slice of a T[new], then resizing the T[new], will
be rare (or at least should be). Normally, a T[new] will be built, and
when it is all done, it is converted to a T[] and there is no longer any
way to resize it.

As expected, but like I said.. this needs to be clear in the spec.  Because
something like this is just confusing (and yes, I know it's not new behavior):

    auto a = new int[10];
    a[0] = 1;
    auto s1 = a[0..1];
    a.length = <some value large enough to force a move>;
    auto s2 = a[0..1];
    s2[0] = 2;
    assert(s1[0] == s2[1]); // fail

Later,
Brad


Well yah but in all languages this is the case. C++'s iterators not only invalidate at the drop of a hat, but you can't really tell whether they're invalid. Java iterators can also be invalidated and may throw an exception.

When resizing a D array, its underlying slices may be *orphaned*. That means they are still valid, they just don't refer to the same data as the array. I think that's a reasonable tradeoff between efficiency and safety.


Andrei

Reply via email to