On Monday, 20 October 2025 at 10:38:23 UTC, Serg Gini wrote:
On Monday, 20 October 2025 at 09:50:35 UTC, Brother Bill wrote:
So all that guidance of tail appending using 'length' and 'capacity' is obsolete. That is, if the capacity > length, then one can safely extend the tail by (capacity - length) elements. The new advice is to just not append to slices either for the base array or any tail slice array. Otherwise, breakage or termination of slice sharing may result.

Do I have that correct?

But I'm not sure about slice capacity. it doesn't make any sense for me when it is non-zero
https://dlang.org/spec/arrays.html#capacity-reserve

I've played with the code and think I understand D's rules for sharing or breaking sharing.

1. Extending the base dynamic array up to (capacity – length) will continue to maintain sharing with derived slices. 2. Extending the base dynamic array beyond (capacity – length) will make a copy of the base dynamic array and break sharing. 3. Extending a derived slice will make a copy of the derived slice and break sharing.

source/app.d
```
import std.stdio;

void main()
{
        extendingBaseArraySmallMaintainsSharing();
        extendingBaseArrayLargeDoesNotMaintainSharing();
        extendingSliceDoesNotMaintainSharing();
}

void extendingBaseArraySmallMaintainsSharing()
{
        writeln("=== extendingBaseArraySmallMaintainsSharing ===");
        int[] slice = [1, 3, 5, 7, 9, 11, 13, 15];
        int[] tailSlice = slice[$ / 2 .. $];
writeln("slice: ", slice, " length: ", slice.length, " capacity: ", slice.capacity, ", &slice[4]: ", &slice[4]); writeln("tailSlice: ", tailSlice, " length: ", tailSlice.length, " capacity: ", tailSlice.capacity, " &tailSlice[0]: ", &tailSlice[0]);

slice.length += (slice.capacity - slice.length); // extend to capacity writeln("slice after: ", slice, " length: ", slice.length, " capacity: ", slice.capacity, ", &slice[4]: ", &slice[4]); writeln("tailSlice after incrementing length by 1: ", tailSlice, " length: ", tailSlice.length, " capacity: ", tailSlice.capacity, " &tailSlice[0]: ", &tailSlice[0]);
        tailSlice[0] = 888;
writeln("After tail slice length increase and changing tailSlice[0] to 888. ", " length: ", tailSlice.length, " capacity: ", tailSlice.capacity);
        writeln("tailSlice: ", tailSlice);
        writeln("slice    : ", slice);
        writeln;
}

void extendingBaseArrayLargeDoesNotMaintainSharing()
{
        writeln("=== extendingBaseArrayLargeDoesNotMaintainSharing ===");
        int[] slice = [1, 3, 5, 7, 9, 11, 13, 15];
        int[] tailSlice = slice[$ / 2 .. $];
writeln("slice: ", slice, " length: ", slice.length, " capacity: ", slice.capacity, ", &slice[4]: ", &slice[4]); writeln("tailSlice: ", tailSlice, " length: ", tailSlice.length, " capacity: ", tailSlice.capacity, " &tailSlice[0]: ", &tailSlice[0]);

slice.length += (1 + slice.capacity - slice.length); // extend just beyond capacity writeln("slice after: ", slice, " length: ", slice.length, " capacity: ", slice.capacity, ", &slice[4]: ", &slice[4]); writeln("tailSlice after incrementing length by 1: ", tailSlice, " length: ", tailSlice.length, " capacity: ", tailSlice.capacity, " &tailSlice[0]: ", &tailSlice[0]);
        tailSlice[0] = 888;
writeln("After tail slice length increase and changing tailSlice[0] to 888. ", " length: ", tailSlice.length, " capacity: ", tailSlice.capacity);
        writeln("tailSlice: ", tailSlice);
        writeln("slice    : ", slice);
        writeln;
}

void extendingSliceDoesNotMaintainSharing()
{
        writeln("=== extendingSliceDoesNotMaintainSharing ===");
        int[] slice = [1, 3, 5, 7, 9, 11, 13, 15];
        int[] tailSlice = slice[$ / 2 .. $];
writeln("slice: ", slice, " length: ", slice.length, " capacity: ", slice.capacity, ", &slice[4]: ", &slice[4]); writeln("tailSlice: ", tailSlice, " length: ", tailSlice.length, " capacity: ", tailSlice.capacity, " &tailSlice[0]: ", &tailSlice[0]);

tailSlice.length += (tailSlice.capacity - tailSlice.length); // extend to capacity writeln("slice after: ", slice, " length: ", slice.length, " capacity: ", slice.capacity, ", &slice[4]: ", &slice[4]); writeln("tailSlice after incrementing length by 1: ", tailSlice, " length: ", tailSlice.length, " capacity: ", tailSlice.capacity, " &tailSlice[0]: ", &tailSlice[0]);
        tailSlice[0] = 888;
writeln("After tail slice length increase and changing tailSlice[0] to 888. ", " length: ", tailSlice.length, " capacity: ", tailSlice.capacity);
        writeln("tailSlice: ", tailSlice);
        writeln("slice    : ", slice);
        writeln;
}
```

Console output:
```
=== extendingBaseArraySmallMaintainsSharing ===
slice: [1, 3, 5, 7, 9, 11, 13, 15] length: 8 capacity: 11, &slice[4]: 237935F1010 tailSlice: [9, 11, 13, 15] length: 4 capacity: 7 &tailSlice[0]: 237935F1010 slice after: [1, 3, 5, 7, 9, 11, 13, 15, 0, 0, 0] length: 11 capacity: 11, &slice[4]: 237935F1010 tailSlice after incrementing length by 1: [9, 11, 13, 15] length: 4 capacity: 0 &tailSlice[0]: 237935F1010 After tail slice length increase and changing tailSlice[0] to 888. length: 4 capacity: 0
tailSlice: [888, 11, 13, 15]
slice    : [1, 3, 5, 7, 888, 11, 13, 15, 0, 0, 0]

=== extendingBaseArrayLargeDoesNotMaintainSharing ===
slice: [1, 3, 5, 7, 9, 11, 13, 15] length: 8 capacity: 11, &slice[4]: 237935F1040 tailSlice: [9, 11, 13, 15] length: 4 capacity: 7 &tailSlice[0]: 237935F1040 slice after: [1, 3, 5, 7, 9, 11, 13, 15, 0, 0, 0, 0] length: 12 capacity: 15, &slice[4]: 237935F2010 tailSlice after incrementing length by 1: [9, 11, 13, 15] length: 4 capacity: 7 &tailSlice[0]: 237935F1040 After tail slice length increase and changing tailSlice[0] to 888. length: 4 capacity: 7
tailSlice: [888, 11, 13, 15]
slice    : [1, 3, 5, 7, 9, 11, 13, 15, 0, 0, 0, 0]

=== extendingSliceDoesNotMaintainSharing ===
slice: [1, 3, 5, 7, 9, 11, 13, 15] length: 8 capacity: 11, &slice[4]: 237935F1070 tailSlice: [9, 11, 13, 15] length: 4 capacity: 7 &tailSlice[0]: 237935F1070 slice after: [1, 3, 5, 7, 9, 11, 13, 15] length: 8 capacity: 11, &slice[4]: 237935F1070 tailSlice after incrementing length by 1: [9, 11, 13, 15, 0, 0, 0] length: 7 capacity: 7 &tailSlice[0]: 237935F0020 After tail slice length increase and changing tailSlice[0] to 888. length: 7 capacity: 7
tailSlice: [888, 11, 13, 15, 0, 0, 0]
slice    : [1, 3, 5, 7, 9, 11, 13, 15]
```

Reply via email to