ref arguments

Jeremie Pelletier jeremiep at gmail.com
Mon Sep 21 11:46:25 PDT 2009


Saaa wrote:
> Steven Schveighoffer wrote:
>> On Mon, 21 Sep 2009 11:12:49 -0400, #ponce <aliloko at gmail.com> wrote:
>>
>>> Is there a reason to use ref instead of in, inout or out ?
>>> I'm using D1 and it's not in the spec.
> 
> It is here in the spec: Function Parameters
> http://www.digitalmars.com/d/1.0/function.html
> 
>> ref and inout are synonymous, ref is preferred, as inout is essentially a 
>> defunct keyword.
>>
>> in means that it's a reference that cannot be changed.  In D1, it means 
>> you cannot change the value, but if the value contains a reference to 
>> something else (like an array), you can change what it points to.
> 
> The spec says: (http://www.digitalmars.com/d/1.0/function.html)
> "For dynamic array and object parameters, which are passed by reference, 
> in/out/ref apply only to the reference and not the contents."
> And: (http://www.digitalmars.com/d/1.0/abi.html)
> "When passing a static array to a function, the result, although declared as 
> a static array, will actually be a reference to a static array."
> 
> Shouldn't it thus be:
> "For array and object parameters, which are passed by reference..."
> ??
> 
> My interpretation for:
>    void  func(in/out/ref int[10]arr)
> "in" arr is a new reference pointing to the passed array.
> "out" arr is a new array of 10 ints initialized to 0.
> "ref" arr is the original reference you passed
> Same for dynamic arrays/objects.

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. 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.
"in" copies the array reference, the local reference AND the referenced 
data are immutable in the method's scope.
"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.
"out" passes a reference to the caller's array reference. The referenced 
  array reference is zeroed and can be modified by the local reference.

If you want a mutable reference to an immutable view on the referenced 
data, use const(int)[], which can also be ref or out.

>> In D2,  it is synonymous with ref const scope (although the scope 
>> attribute  doesn't yet mean anything), so you cannot change anything it 
>> points to.
>>
>> out means that it's a reference that you are always going to overwrite.  I 
>> believe the compiler even initializes the value for you upon function 
>> entry.
>>
>> So in summary:
>>
>> inout: don't use it.
>> ref: Use this for pass by reference for a value that you may or may not 
>> change.
>> in: Use this for pass by reference for a value that you won't change
>> out: Use this for pass by reference for a value that you will *always* 
>> change.
> What do you mean by: "pass by reference for a value"?
> It reads like it creates a reference to a value.
> in and out don't create a reference, do they?
> 
> 
> My interpretation for:
>    void  func(in/out/ref int i)
> "in" i is a new int initialized to the passed int.
> "out" i is a new int set to 0.
> "ref" i is a reference to the original passed int?
> 
> Are my interpretations correct??
> Anyways, I think this deserves a bit more explaination in the spec.
> Ref is never explained.
> 
>> -Steve 
> 

"<none>" would be a mutable copy.
"in" would be immutable copy.
"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.

Jeremie


More information about the Digitalmars-d-learn mailing list