On Wed, 08 Jul 2009 23:09:52 -0400, Tim Matthews <tim.matthe...@gmail.com>
wrote:
Steven Schveighoffer wrote:
On Wed, 08 Jul 2009 02:48:31 -0400, Tim Matthews
<tim.matthe...@gmail.com> wrote:
Was this a design choice, bug, undefined behavior, etc...?
design choice.
A slice *is* an array in the current design. Increasing the length
may or may not make a copy of it. An array slice doesn't know it was
originally part of another array (i.e. there are no references back to
the original array) so how would it know that there is data around it?
The only exception is appending to a prefix slice. If a slice starts
at the front of an allocated array, the runtime cannot tell that it was
not the original array, so it clobbers data that was in the original
array:
char[] str = "blah".dup;
char[] sl = str[0..1];
sl ~= "r";
assert(str == "brah");
BTW, all of this is defined behavior, see
http://www.digitalmars.com/d/2.0/arrays.html#resize
-Steve
I thought a slice would behave slighty different due to some sort of
meta data that is a separate area of memory so it doesn't effect D's abi.
Anyway if anyone gets here through a search engine the correct code
assuming you can guarantee it is a slice and that doesn't go out of
bounds. It is a systems language after all :)
module test;
import std.stdio;
void resizeView(T)(ref T[] slice, size_t newLength)
{
(cast(size_t*)(&slice))[0] = newLength;
}
void main()
{
char[5] a = "hello";
char[] b = a[1..3];
writeln(a); //(hello)
writeln(b); //(el)
resizeView(b, b.length+1);
writeln(a); //(hello)
writeln(b); //(ell)
}
This is really not a good idea. You've removed one of the core features
of the array -- memory safety. Doing this is just asking for memory
corruption. You should either re-slice the original array, or create a
type that has a reference to the original array so it can be resliced:
start with:
struct TimSlice(T)
{
T[] slice;
alias slice this;
T[] srcArray;
// override length property
size_t length() {return slice.length;}
void length(size_t) {/* use srcArray here to re-slice */}
}
This is assuming you are using D2, of course. With D1, it's more
difficult.
-Steve