www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Why are fixed length arrays passed by value while variable are passed

reply "ixid" <nuaccount gmail.com> writes:
I know this will not be changed, I just want to understand why it 
is as it is.

My naive thought is that consistency is the best scheme and that 
everything should have been passed by value or everything by 
reference unless the user specifies otherwise.

I have read a comment by Andrei that they tried making fixed 
length arrays into reference types but it did not work well. Did 
the current situation arise through the reality of language 
development or is there a reason for the inconsistency?
Apr 18 2013
next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2013-04-18 15:37, ixid wrote:
 I know this will not be changed, I just want to understand why it is as
 it is.

 My naive thought is that consistency is the best scheme and that
 everything should have been passed by value or everything by reference
 unless the user specifies otherwise.

 I have read a comment by Andrei that they tried making fixed length
 arrays into reference types but it did not work well. Did the current
 situation arise through the reality of language development or is there
 a reason for the inconsistency?
An array is represent using a struct with a pointer to the array data and the length, like this: struct Array { void* ptr; size_t length; } The struct is passed by value, but since it contains a pointer to the data it will be passed by reference. Note that if you do: void foo (int[] a) { a ~= 3; } auto b = [3, 4]; foo(b); The caller will not see the change made by "foo". Don't know if this explanation helped you to understand. -- /Jacob Carlborg
Apr 18 2013
parent reply "ixid" <nuaccount gmail.com> writes:
 An array is represent using a struct with a pointer to the 
 array data and the length, like this:

 struct Array
 {
     void* ptr;
     size_t length;
 }

 The struct is passed by value, but since it contains a pointer 
 to the data it will be passed by reference. Note that if you do:

 void foo (int[] a)
 {
     a ~= 3;
 }

 auto b = [3, 4];
 foo(b);

 The caller will not see the change made by "foo".

 Don't know if this explanation helped you to understand.
What does a fixed length array look like when passed, doesn't it have a similar payload of data and length? I take it you mean the struct method is the variable length array.
Apr 18 2013
next sibling parent "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On 2013-04-18, 16:20, ixid wrote:

 An array is represent using a struct with a pointer to the array data  
 and the length, like this:

 struct Array
 {
     void* ptr;
     size_t length;
 }

 The struct is passed by value, but since it contains a pointer to the  
 data it will be passed by reference. Note that if you do:

 void foo (int[] a)
 {
     a ~= 3;
 }

 auto b = [3, 4];
 foo(b);

 The caller will not see the change made by "foo".

 Don't know if this explanation helped you to understand.
What does a fixed length array look like when passed, doesn't it have a similar payload of data and length? I take it you mean the struct method is the variable length array.
The fixed length array is much more similar to a struct. An int[2], for instance, is in many ways equivalent to struct { int a; int b; }. Two ways this is visible is that static arrays are allocated on the stack, and take up space in a struct or class the same way a struct would: struct S1 { int[] a; } static assert( S1.sizeof == int[].sizeof ); struct S2 { int[17] a; } static assert( S2.sizeof == 17 * int.sizeof ); Also, like Jacob wrote, there is the difference of ref/value semantics when embedded in a struct/class. If I have these two functions: void foo1( S1 s ) { s.a[0] = 7; } void foo2( S2 s ) { s.a[0] = 7; } void test( ) { S1 s1 = S1(new int[4]); S2 s2 = S2(); foo1(s1); foo2(s2); } The values in s1 will have changed, while those in s2 will not. All in all, static arrays are treated as value types everywhere else, and so treating them as value types when passed to a function makes more sense. -- Simen
Apr 18 2013
prev sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 04/18/2013 07:20 AM, ixid wrote:

Jacob Carlborg said:

 An array is represent using a struct with a pointer to the array data
 and the length, like this:

 struct Array
 {
     void* ptr;
     size_t length;
 }
The terms "array" and "slice" are commonly interchanged but I think it adds to the confusion. The above is the definition of a slice. An array is simply a collection of objects placed next to each other.
 The struct is passed by value, but since it contains a pointer to the
 data it will be passed by reference. Note that if you do:

 void foo (int[] a)
 {
     a ~= 3;
 }

 auto b = [3, 4];
 foo(b);

 The caller will not see the change made by "foo".

 Don't know if this explanation helped you to understand.
What does a fixed length array look like when passed, doesn't it have a similar payload of data and length?
No. It is all of the elements side by side. That is the definition of an array. int[3] a; assert(a.sizeof == ((a[0]).sizeof * a.length)); assert(cast(void*)&a == cast(void*)&(a[0])); A fixed-length array does not have a ptr or length member. The former is simly the address of the fixed-length array itself and the latter is a compile-time constant.
 I take it you mean the struct method
 is the variable length array.
Yes. The struct above is a slice. (Although, in reality length is defined before ptr.) Ali
Apr 18 2013
prev sibling parent reply "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Thursday, 18 April 2013 at 13:37:45 UTC, ixid wrote:
 I know this will not be changed, I just want to understand why 
 it is as it is.

 My naive thought is that consistency is the best scheme and 
 that everything should have been passed by value or everything 
 by reference unless the user specifies otherwise.
Classifying types as passed by value and passed by reference types is a little bit confusing sometimes) In D, like in C, everything is passed by value (unless parameter is specified as ref, also note that in C passing by reference is a simulation done by pointers). Confusion comes when there is data which points to another data. Learning how data types are constructed is better approach than classifying their categories. The former sometimes can explain what the latter cannot: http://dpaste.dzfl.pl/7744d11e AA array behaves like a reference type, but when it is reset to null, it acts like a value type. Contradiction is caused by complex data structes with mixed structs and pointers in AA implementation.
 I have read a comment by Andrei that they tried making fixed 
 length arrays into reference types but it did not work well. 
 Did the current situation arise through the reality of language 
 development or is there a reason for the inconsistency?
I don't consider curent situation with static arrays as incosistent.
Apr 18 2013
next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 18 Apr 2013 11:26:22 -0400, Maxim Fomin <maxim maxim-fomin.ru>  
wrote:

 On Thursday, 18 April 2013 at 13:37:45 UTC, ixid wrote:
 I know this will not be changed, I just want to understand why it is as  
 it is.

 My naive thought is that consistency is the best scheme and that  
 everything should have been passed by value or everything by reference  
 unless the user specifies otherwise.
Classifying types as passed by value and passed by reference types is a little bit confusing sometimes) In D, like in C, everything is passed by value (unless parameter is specified as ref, also note that in C passing by reference is a simulation done by pointers). Confusion comes when there is data which points to another data. Learning how data types are constructed is better approach than classifying their categories. The former sometimes can explain what the latter cannot: http://dpaste.dzfl.pl/7744d11e AA array behaves like a reference type, but when it is reset to null, it acts like a value type. Contradiction is caused by complex data structes with mixed structs and pointers in AA implementation.
AA's are not passed by reference, they ARE a reference. That reference is ALWAYS passed by value, unless ref is used. The problem with AA's is that the special reference null mutates upon first addition to the AA, and never changes afterwards, unless reassigned. It is always passed by value. In fact, if default construction allowed allocating the initial reference (or null wasn't treated specially), we wouldn't have that problem. -Steve
Apr 18 2013
prev sibling parent "ixid" <nuaccount gmail.com> writes:
 I don't consider curent situation with static arrays as
 incosistent.
When correctly understood is isn't as inconsistent, thank you for explaining, this was the knowledge I was after.
Apr 18 2013