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.

Reply via email to