assumeSafeAppend inconsistent when multiple slices in use
Steven Schveighoffer
schveiguy at yahoo.com
Thu Apr 7 13:43:06 PDT 2011
On Thu, 07 Apr 2011 15:22:10 -0400, simendsjo <simen.endsjo at pandavre.com>
wrote:
> On 05.04.2011 22:04, Steven Schveighoffer wrote:
> > However, a does not end on the master slice, so its capacity is 0.
> Note
> > that technically using a[1..$] is undefined at this point since the
> > runtime considers those elements 'unused'.
>
> What do you mean be undefined in this context? Do you mean because it
> can be overwritten like this?
>
> int[] a = [1,2];
> int[] b = a[0..1];
> b.assumeSafeAppend();
> b.length += 1;
> assert(a == [1,0]); // a[1] overwritten as int.init is called on the
> element
yes, although the above does not represent technically undefined behavior
-- you didn't access a[1] when a[1] was not considered part of the used
space.
> Or is it because it's outside what the runtime considers part of the
> used array and is free to do what it want's with it?
Yes on this count too.
For example, it might be that some runtime implementations, when you call
assumeSafeAppend, could write 0xdeadbeef into the elements that are
no-longer valid. This is perfectly acceptable, and as long as you don't
access those elements, the behavior should be predictable.
I'm not a language lawyer, so maybe the better term is 'implementation
defined'. I'm not sure.
> Or doesn't the gc track slices with an endpoint greater than the current
> endpoint so it might return memory to the OS?
The GC does not partially deallocate a block. These slices will still
point to the block, so it won't be collected. Note that the GC proper
does not really "know" about the used length. It just knows that there is
an allocated block of size X. Only the runtime knows what data is 'used'
and what is 'free' inside the block (specifically the array management
part of the runtime).
-Steve
More information about the Digitalmars-d-learn
mailing list