On Thursday, 17 December 2020 at 18:42:54 UTC, H. S. Teoh wrote:
Are you sure?
My understanding is that capacity is always set to 0 when you
shrink an array, in order to force reallocation when you append
a new element. The reason is this:
int[] data = [ 1, 2, 3, 4, 5 ];
int[] slice = data[0 .. 4];
writeln(slice.capacity); // 0
writeln(data.capacity); // 7 <--- N.B.
slice ~= 10;
writeln(slice); // [1, 2, 3, 4, 10]
writeln(data); // [1, 2, 3, 4, 5]
Notice that slice.capacity is 0, but data.capacity is *not* 0,
even after taking the slice. Meaning the array was *not*
deallocated.
Why is slice.capacity set to 0? So that when you append 10 to
it, it does not overwrite the original array (cf. last line of
code above), but instead allocates a new array and appends to
that. This is the default behaviour because it's the least
surprising -- you don't want people to be able to modify
elements of your array outside the slice you've handed to them.
If they want to append, they get a copy of the data instead.
In order to suppress this behaviour, use .assumeSafeAppend.
T
How does this connect to the array with zero elements? According
to your explanation if I have understood it correctly, capacity
is also indicating if the pointer has been "borrowed" from
another array forcing an allocation whenever the array is
modified. However, if capacity is zero when the array length is
zero, then you would get a allocation as well, regardless if
there was a previous allocated array.