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'.

Reply via email to