Debug help - Programming in D - extending tail slice terminates sharing unexpectedly. Page 69, 70
Brother Bill
brotherbill at mail.com
Mon Oct 20 10:47:09 UTC 2025
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]
```
More information about the Digitalmars-d-learn
mailing list