ref arguments
Jeremie Pelletier
jeremiep at gmail.com
Mon Sep 21 17:52:06 PDT 2009
Saaa wrote:
> Jeremie Pelletier wrote:
>
>> You cannot have static array be ref or out. You must use int[] arr instead
>> and let the caller specify the length.
>>
>> Array in D are already references to their data, it's a 8bytes (or 16bytes
>> on x64) value containing a pointer and a length.
>
> Ok, this I got correct :)
>
>> So the following prototype: void func(<none>/in/ref/out int[] arr);
>>
>> would have the following semantics:
>>
>> "<none>" copies the array reference, the referenced data is mutable.
>> Modifying the local reference does not change the caller's reference.
>
> Modifying the local referenced data does not change the caller's referenced
> data.
> So only if the referenced data is mutated, a copy will be made?
> Test seems to back this up.
What I meant is that modifying the local reference does not change the
caller's reference, but both references point to the same data.
>> "in" copies the array reference, the local reference AND the referenced
>> data are immutable in the method's scope.
>
> What, there is a difference between <none> and "in" ??
> Where can I about read this?
> In the example "int foo(int x, ..." on the functions page x is "in".
> Are we maybe talking about a different D? D1
> I really really wish to understand this stuff.
> <info> I know about how in c a function stack is created.
I don't think theres a difference in D1, in D2 there is:
void Foo(in int[] bar);
here typeof(bar).stringof would say const(int[]).
http://digitalmars.com/d/2.0/function.html
"If no storage class is specified, the parameter becomes a mutable copy
of its argument."
>> "ref" passes a reference to the caller's array reference, the referenced
>> data is mutable. Modifying the local reference also changes the caller's
>> reference.
>
> Same as <none> except that it doesn't create a copy on mutate?
Not the same, no storage class will make a copy of the reference, which
points to the same data as the caller's reference. "ref" makes a
reference to the caller's reference, so you can modify it *and* the data
it points to.
Here's an example:
void main() {
int[] arr = new int[64];
arr[0] = 10;
foo(arr);
assert(arr.length == 10); // True because foo changed our reference
with its own
}
void foo(ref int[] arr) {
assert(arr[0] == 10); // True because arr points to the same data
as the caller's
arr = new int[10];
}
This is the difference between being able to modify the array data and
the array reference.
>> "out" passes a reference to the caller's array reference. The referenced
>> array reference is zeroed and can be modified by the local reference.
>
> Compared to returning a locally(to the function) created array, here
> no allocation might be needed if the passed array is big enough.
"out" does not create the array data, only a reference to a null array
reference in the caller's frame. You still need to allocate data for the
array. Take the above example and change ref to out, the assert in foo
would fail because arr is set to a null reference, but the assert in
main would succeed because foo modified it.
>> If you want a mutable reference to an immutable view on the referenced
>> data, use const(int)[], which can also be ref or out.
>
> out const(int)[] will create a array of zero's which you cannot change?
No, it will nullify the reference it is given allowing the method to
assign a new reference to it for the caller to use, but wont be able to
modify its data after assigning the reference.
> Why isn't there a nice table about this?
> columns: local reference/data with/without mutation, caller reference/data
> with/without mutation
> rowns: <none>, in, out, ref
> cells: array.ptr/length/data
> Or, where should I put it after creating it.
I had to learn it through trial and error myself :) If you do make such
a table you could submit it as an improvement in bugzilla.
>> void func(in/out/ref int i)
>>
>> "<none>" would be a mutable copy.
>> "in" would be immutable copy.
> I can't get over the idea that in and none aren't the same
> Really, D1? :D
> In my test program I can change local i using "in"
>
>> "out" is a reference to the caller's int initialized to 0.
>
>> "ref" is a reference to the caller's int.
>
>> "in" and "const" are only really useful with types which are already
>> references, such as pointers, arrays and objects.
>
> Hope I got it right..
Oops, I was talking in the context of D2, where 'in' is an alias for
'const scope'.
More information about the Digitalmars-d-learn
mailing list