dsimcha wrote:
== Quote from Ali Cehreli (acehr...@yahoo.com)'s article
I haven't started reading Andrei's chapter on arrays yet. I hope I won't find
out that the following behavior is expected. :)
import std.cstream;
void modify(int[] a)
{
    a[0] = 1;
    a ~= 2;
    dout.writefln("During: ", a);
}
void main()
{
    int[] a = [ 0 ];
    dout.writefln("Before: ", a);
    modify(a);
    dout.writefln("After : ", a);
}
The output with dmd 2.035 is
Before: [0]
During: [1,2]
After : [1]
I don't understand arrays. :D
Ali

This is one of those areas where the low-level details of how arrays are
implemented arrays leak out.  This is unfortunate, but in a close-to-the-metal
language it's sometimes a necessary evil.

(Dynamic) Arrays are structs that consist of a pointer to the first element and 
a
length.  Essentially, the memory being pointed to by the array is passed by
reference, but the pointer to the memory and the length of the array are passed 
by
value.  While this may seem ridiculous at first, it's a tradeoff that allows for
the extremely convenient slicing syntax we have to be implemented efficiently.

When you do the a[0] = 1, what you're really doing is:

*(a.ptr) = 1;

When you do the a ~= 2, what you're really doing is:

// Make sure the block of memory pointed to by a.ptr
// has enough capacity to be appended to.
a.length += 1;
*(a.ptr + 1) = 2;

Realistically, the only way to understand D arrays and use them effectively is 
to
understand the basics of how they work under the hood.  If you try to memorize a
bunch of abstract rules, it will seem absurdly confusing.

main.a starts as:
struct {
  int length = 1;
  int *data = 0x12345; // some address pointing to [ 0 ]
}

inside of modify, a is:
struct { // different then main.a
   int length = 2;
   int *data = 0x12345; // same as main.a data [ 1, 2]
}

back in main:
struct { // same as original main.a
  int length = 1;
  int *data = 0x12345; // hasn't changed address, but data has to [ 1 ]
}


To get the expected results, pass a as a reference:

void modify(ref int[] a);

Reply via email to