Fawzi Mohamed wrote:
On 2009-10-16 13:54:03 +0200, Max Samukha <spam...@d-coding.com> said:

On Fri, 16 Oct 2009 02:53:20 -0700, Walter Bright
<newshou...@digitalmars.com> wrote:

Don wrote:
Max Samukha wrote:
// arrays are true reference types
int[new] a = [1, 2, 3];
b = a;
a.length = 22;
assert (a.length == b.length);

This makes perfect sense to me. The rule would be:
If 'x' is T[new], then:
x = y; _always_ copies y into a {length, capacity-specified block},
unless it already is one. x is given a pointer to the start of that block.
x[] = y[]; does a memcpy, regardless of whether y is a T[new] or a T[].

Right. Assignment of a reference type does not copy the values of what
is referred to. Only the reference is copied.

I think it would be very strange to have T[] behave like a reference
type (which it does now) and T[new] to behave like a value type.

By "true reference type", I meant:

struct ArrayRef
{
    Array* ptr;
}

struct Array
{
   void* data;
   size_t length;
   // size_t capacity;
}

The fat reference approach for arrays has sucked from day one (IMHO).

I think performance-critical code will use slices (read - ranges)
anyway, so the additional allocation and indirection is not a big
issue.

Yes exactly his is the most logically pleasing handling of resizable array, a resizable array is a ArrayRef (and the capacity there should not be commented out).

Obviously this has a cost (extra indirection to access data).

Fawzi

Yes, but you could allocate the data immediately after the Array structure, so you only have one allocation. And in the common case, where it never exceeds the original capacity, they stay together and preserve cache locality.

 void *data;   // = &raw_data;
 size_t length;
 size_t capacity; // = 512
 ubyte[512] raw_data;

Reply via email to