resizeable arrays: T[new]

Frits van Bommel fvbommel at REMwOVExCAPSs.nl
Mon Jun 4 05:28:34 PDT 2007


Walter Bright wrote:
> 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
> 
>    a.length = 6;   // error, static array
>    b.length = 6;   // error, dynamic array is not resizeable
>    c.length = 6;   // ok
>    b = c;          // ok, implicit conversion of resizeable to dynamic
>    c = b;          // error
>    c = b[0..n];    // error
>    b = c[0..n];    // ok, but watch out if c is later resized
>    b = c[0..n].dup; // ok, no worries
>    c = cast(T[new])b; // ok, but this will be deliberate

What about
	c = a;
?
I have several places where I have functions that follow this pattern:
---
T[] foo(<parameters>, T[] buffer = null) {
     buffer.length = <something>;
     <fill buffer>
     return buffer;
}
---
These are intended to be usable with "buffer" being either a 
stack-allocated static array or a heap-allocated dynamic array. If the 
passed buffer is big enough a slice is returned, otherwise it gets 
enlarged (and possibly reallocated on the heap).
I guess with this proposed modification I'd want to accept and return a 
"T[new]", but will that allow static arrays (stack-allocated) to be 
passed in?
I'd hate to have to write two different functions, one for static arrays 
and slices and one for resizable arrays... (and I'm not fond of the idea 
of extra casts to make it work with a single function)

Also, I often write toString() members of objects (and other functions 
returning strings) like this:
---
char[] toString() {
     auto ret = "prefix";
     foreach (elt; children) {
         ret ~= elt.toString();
         // perhaps append a separator here
     }
     // if separators were appended, remove the last one here
     ret ~= "postfix";
     return ret;
}
---
Will these need to be changed? (probably a .dup after the "prefix" string)
(Since string constants are also static arrays, this is the same basic 
issue as above)

> I think this will entail only very rare changes to user code, but will 
> be a big improvement in type safety. Note that it will *still* possible 
> for array resizing to affect other slices into the same array, but it's 
> far, far less likely to happen inadvertently. The attractiveness of this 
> solution is it nearly completely solves the problem with zero runtime cost.

I think I may need to make quite some changes actually, though the 
changes required to the latter code sample I gave will be minimal.


Another question, will the following be allowed:
---
class Base {
     abstract char[] foo();
}

class Derived : Base {
     override char[new] foo() { assert(0, "Not implemented yet"); }
}
---
?



More information about the Digitalmars-d-announce mailing list