Passing dynamic arrays

Jesse Phillips jessekphillips+D at gmail.com
Mon Nov 8 16:24:27 PST 2010


spir Wrote:

> No, they are _not_ passed by reference. Stop saying that, this is precisely what causes confusion. This is reference semantics:

void main() {
   auto a = new int[1];
   auto b = a;
   a[0] = 5;
   assert(a == b);
   assert(a[0] == b[0]);
   assert(a is b);
   writefln("%x == %x", &a[0], &b[0]);
   moreExample(a, cast(uint) &a[0]);
}

void moreExample(int[] a, uint aAddr) {
   assert(cast(uint)&a[0] == aAddr);
   writefln("%x == %x", &a[0], aAddr);
}

> D arrays do not work that way: the kind of struct is *copied*, not referenced; arrays themselves are *values*. So that changes to the content that requires reallocation breaks the relation.

The struct you are referring to _is_ the reference. There is no such thing as "copy by reference," everything is copied by value. However, some values are just a reference to another location.

> (Additional confusion is brought by the fact that, if a is an array, after "b=a" (b is a) yields true, for any reason, but this is also wrong. I guess 'is' is overloaded for arrays to compare the adresses of the contents instead of the ones of the array-structs, but this is misguided.)

The array-struct is the reference, so it is what gets compared. That means both the internal pointer and length must be the same. Just because the reference is more than an address does not make it any less a reference.

void main() {
   auto a = new int[2];
   a[0] = 5;
   a[1] = 10;
   auto b = a.dup;
   auto c = a[0..1];
   assert(a == b);
   assert(a[0] == b[0]);
   assert(a !is b);
   assert(a !is c);
}

The distinction is that an Array can have its reference changed by resizing (which is not an option for other reference types).


More information about the Digitalmars-d mailing list