arrays && functions && pointers

Regan Heath regan at netwin.co.nz
Sun Jun 18 17:25:17 PDT 2006


On Sun, 18 Jun 2006 23:49:09 +0000 (UTC), MM <MM_member at pathlink.com>  
wrote:
> Here a simple question, I hope.
>
> In C I was always told arrays should not be send to my functions as if,  
> but only
> a pointer should be supplied. Which was a *****.

Are you referring to something like (in C):

void foo(char *string) {}
char array[100];
foo(array);

In this case C automatically passes a pointer to the first element of the  
array, rather than copying the entire array.

> How is this done in D?

In D and array is a pseudo reference pseudo value type. It is in reality a  
struct in the form:

struct array {
   int length;
   void *data;
}

or similar where "data" refers to the actual content of the array. Passing  
the array passes a copy of the structure (like a value type) but does not  
cause a copy of the data (like a reference type). This is fast and  
efficient enough that there is no reason not to just pass it, much as you  
do in C, eg.

void foo(char[] string) {}
char[100] array;
foo(array);

note that the above "array" is a fixed/static array of 100 characters, but  
it can be passed as a dynamic array [] of variable length because the  
function gets a copy of the structure which in turn refers to the original  
static data.

Therefore..

If you pass an array as "in" (the default method) any modifications you  
make to the array length or to the data pointer (by assigning a new array  
slice to it or similar) will not be propagated back to the array you  
passed to the function as they only happen to the copy you get inside the  
function. However, any changes you make to the data to which the array  
refers does propagate, because there is only 1 copy of it. eg.

void foo(char[] string) {
   string.length = 5;    //does not propagate
   string = string[1..$] //does not propagate
   string[0] = 'a';      //does propagate (actually modifies 2nd char  
(index 1) of external array)
}

However..

If you pass an array as "inout" or "out" then you do not get a copy of the  
structure but you get the actual structure itself, so when/if you change  
the length or data pointer you're change the array which you passed  
directly and you will see the changes propagate.

void foo(inout char[] string) {
   string.length = 5;    //does propagate
   string = string[1..$] //does propagate
   string[0] = 'a';      //does propagate
}

Meaning..

You cannot pass a fixed/static array as "inout" or "out" to a function  
expecting a dynamic char[] because you cannot modify a fixed/static array  
length or data pointer, you'll get an error like this if you try to pass  
one.
   cast(char[])(test) is not an lvalue

In short, just pass your D arrays to functions as is, whether they're  
fixed or dynamic.

Regan



More information about the Digitalmars-d-learn mailing list