On 7/30/20 11:58 AM, wjoe wrote:
I just stumbled upon code like this:

struct Foo(T)
{
     T[] b;

     this(int n)
     {
         b.reserve(n);
         b.length = n;
     }
}

..reserve looks redundant.

It is, in this case. Reserve will extend the allocated length to n, but not adjust the slice, and setting the length will adjust the slice and consume that data from the block. Just setting length has the same effect.


The docs are explaining .length nicely, however lack any specifics about reserve.

Changing the length of an array may relocate and copy. New items are initialized with T.init - is that true for both length and reserve ?

reserve preallocates data for use in appending, but does not alter the length of the specified array.

It's like saying, "I'm going to append enough elements to this array so the total length is N." It's very much tied to appending.

Note that reserve may do nothing, if there is already at least N elements available.

Also there's .capacity - is that equivalent to reserve ?

Capacity tells you how many total elements the current reserved space can hold. If the array is not appendable, then this returns 0.

Another curiosity I noticed is that the docs say that the runtime tries to resize in place, however:

b = b[0..$-1]; if length==1 seems to collect the memory at once because if it's immediately followed by b.length = 1; or b ~= someT; b.ptr points to a new address.
Why ?

Because you would be overwriting the data already in the array.

For example:

auto a = b;
b = b[0 .. $-1];
b ~= someT;

If that last line is done in-place, then it overwrites a[$-1].

If you know that it's OK to do this, then you should call assumeSafeAppend on the array (which will adjust the "used" space down to the current array).

I know that b=b[0..0]; is equivalent to b = null;

No, if slicing b to b[0 .. 0], b.ptr does not change. b = null sets the pointer to null. In the former case, if you called assumeSafeAppend on it, then it could append in-place at that point. With the null pointer, it would reallocate.

-Steve

Reply via email to