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