resizeable arrays: T[new]

Oskar Linde oskar.lindeREM at OVEgmail.com
Mon Jun 4 12:46:40 PDT 2007


Walter Bright skrev:
> Oskar Linde wrote:
>> 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:
>>
>> An excellent suggestion. And I'm not only saying that because I have 
>> suggested this several times myself. :p
> 
> Can you point me to the posting(s)? You should get the credit for being 
> first.

Looking back at some of my posts, I don't think I ever made a public 
newsgroup post actually suggesting D change in this way... For the 
reason that I never dared to believe such a change could ever happen. I 
found some rants on the topic of the separate semantics of slices and 
resizable arrays, but it is hardly posts I feel very proud of. :p

http://www.digitalmars.com/d/archives/digitalmars/D/bugs/bug_or_feature_9420.html#N9425
http://www.digitalmars.com/d/archives/digitalmars/D/learn/3521.html#N3593
http://www.digitalmars.com/d/archives/digitalmars/D/learn/3354.html#N3357

>>>    T[n]   a;  // static array
>>>    T[]    b;  // dynamic array
>>>    T[new] c;  // resizeable array
>>
>> I'd propose a different nomenclature:
>>
>> T[n]   a;  // static array
>> T[]    b;  // (array) slice
>> T[new] c;  // dynamic array
> 
> I like "resizeable" array because it is pretty clear what it does. 

Ok, another suggestion: (Sneakily injecting the [*] too... :)

T[n]   a;  // static array
T[]    b;  // array view
T[*]   c;  // dynamic array

IMHO, "array view" is a better description than "dynamic array". But it 
depends on your point of view, of course.

>> I also agree with others that there are better alternatives to "new". 
>> T[*] is my favorite.
> 
> Looks like C99's VLA.

Afaik, it is only used for vla _prototypes_ in C99, and is that really a 
problem? It is not like the compiler won't warn you if you write:

extern(C) void foo(int,int[*]);

right? And I don't really see how using T[*] for resizable arrays in D 
is any different from using T[] for non-resizable ones -- T[] also means 
something slightly different in C99.

>> Short version: You always want to pass ref T[new]. Forgetting ref is 
>> probably a bug, but is silently accepted by the compiler. Ergo, ref 
>> should be the default. :)
> 
> Frits has posted a realistic use case that argues it shouldn't be.

I presume you mean:

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)."""

The buffer.length = <something>; in the use case might be a neat trick, 
but is it really that essential? Consider the rewrite: (T[] means 
non-resizable dynamic array)

T[] foo(<parameters>, T[] buffer = null)
{
     T[] ret = buffer.length >= needed_capacity
             ? buffer[0..needed_capacity]
             : new T[needed_capacity];
     <fill ret>
     return ret;
}

The only advantage of the original code is that it might be able to 
squeeze a few extra bytes out of a buffer that for some reason would not 
be at its full capacity. But is that really a feature? I would 
personally not have expected this assert to potentially fail:

T[] buffer = new T[1000];
T[] ret = foo(buffer);
assert(ret.length <= buffer.length || ret.ptr != buffer.ptr);

So I don't really see what you gain from being able to pass a resizable 
array by value and then change its length. At least not compared to what 
you gain by not being able to do that.

/Oskar



More information about the Digitalmars-d-announce mailing list