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