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