resizeable arrays: T[new]
Sean Kelly
sean at f4.ca
Mon Jun 4 13:51:24 PDT 2007
Walter Bright wrote:
> Sean Kelly wrote:
>> Walter Bright wrote:
>>> (The problem is if I pass a slice to a function, and then that
>>> function reallocates the slice by changing the length or appending to
>>> it, it can affect other slices into the same data in very
>>> hard-to-explain ways.
>>
>> I'm not sure I understand how a reallocation could affect other slices
>> into the same data. If a reallocation occurs, that reallocation will
>> be into entirely new memory, provided the slice doesn't start at the
>> head of a memory block. Is it the condition I just mentioned that's a
>> problem? If so, I suppose it is one way to trick the compiler into
>> thinking the reference no longer refers to const data, when in fact it
>> does. If not, could you point me in the right direction?
>
> Given:
>
> int[] a = new int[7];
> int[] b = a[1..6];
> b[1] = 2; // writes through to a[2]
> b.length = 4;
> b[1] = 3; // writes through to a[2]
> b.length = 6;
> b[1] = 4; // does not write through to a[2]
Okay, so it is related to non-reallocating changes. Thanks.
>>> Now, it turns out that it is very rare for a function to legitimately
>>> want to resize a buffer passed to it. So we finally hit on the idea
>>> of making a resizeable array a different type, say:
>>>
>>> T[n] a; // static array
>>> T[] b; // dynamic array
>>> T[new] c; // resizeable array
>>
>> Well, I think it is very rare for a function to want to resize an
>> array that isn't passed by reference. My first reaction would be to
>> disallow resizing of non-ref array parameters entirely. Since
>> resizing may occur in place, this could be seen as a mutating
>> operation on the underlying data. If the user wants to resize a
>> non-ref array parameter for local use he use assign ops and such.
>
> That was my first reaction too, but Frits posted a reasonable use case.
Do you mean:
T[] foo(<parameters>, T[] buffer = null) {
buffer.length = <something>;
<fill buffer>
return buffer;
}
Wouldn't it work if changed to this:
T[] foo(<parameters>, T[] buffer = null) {
if( buffer.length < newSize )
buffer = new T[newSize];
<fill buffer>
return buffer;
}
I think it's arguable that the second form is also more meaningful given
that the array is not passed by reference.
Sean
More information about the Digitalmars-d-announce
mailing list