On Thursday, 17 October 2013 at 19:23:37 UTC, Vitali wrote:
I'm not accusing D having a bug here. I'm saying that in my
eyes a reallocation of the array referenced by the slice is not
useful, when capacity is still available.
There is no capacity available for the binary concatenation like
that.
Given this:
arr = arr[0..index] ~ arr[index+1..$];
arr[index] is, as far as this function can tell anyway, still in
use. The concat operator never overwrites in-use data.
Consider this example:
int[] a = [1,2,3,4];
void foo(int[] b) {
int[] c = b ~ 4;
}
foo(a[0 .. 2]);
Surely you wouldn't expect a == [1,2,4] now. But, that's what
would happen if your function remove function didn't allocate!
a[0 .. 2] would become [1,2] with a capacity of 4, because that's
the original length.
Then b ~ 4 sees that there's capacity, and then appends in place,
writing b.length++; b[3] = 4;
but assert(&b[3] is &a[3]), so that just overwrote a's data. But
since b and c are both local variables, that's certainly not what
you intended.
Your example is a little less clear, since it takes the slice by
reference, but it is still the same idea: there might be other
slices to that same data that should not be overwritten.
A new allocation is the only way to be sure.
If you want to overwrite it though, your remove function can just
copy the data itself without reallocation.
"Slicing does not copy the slice's data. It creates a new
slice value that points to the original array. This makes slice
operations as efficient as manipulating array indices."
D does slicing the same way. Your problem is with
appending/concatenating.