ref arguments

Jeremie Pelletier jeremiep at gmail.com
Mon Sep 21 11:28:09 PDT 2009


Steven Schveighoffer wrote:
> On Mon, 21 Sep 2009 12:23:46 -0400, Jeremie Pelletier 
> <jeremiep at gmail.com> wrote:
> 
>> Steven Schveighoffer wrote:
>>> On Mon, 21 Sep 2009 11:51:28 -0400, Jarrett Billingsley 
>>> <jarrett.billingsley at gmail.com> wrote:
>>>
>>>> On Mon, Sep 21, 2009 at 11:43 AM, Steven Schveighoffer
>>>> <schveiguy at yahoo.com> wrote:
>>>>
>>>>> 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.
>>>>
>>>>> in: Use this for pass by reference for a value that you won't change
>>>>
>>>> No, sorry, this is wrong. In D1, 'in' is the default (pass by value)
>>>> and does nothing.
>>>  Oh, that's... um useless...  Pardon me for thinking it meant 
>>> something ;)
>>>  I'm pretty sure it means something in D2 though.
>>>  -Steve
>>
>> 'in' means 'const scope' in D2, which is using pass-by-value semantics.
> 
> Yes, you are right.  I can't see the benefit to it, so I guess my 
> recommendation is not to ever use in (use const instead).

I disagree, I have different uses for both. I use 'in' when the 
reference will not leave the function's scope and const when it does. 
Both are immutable views on the data but with different usage semantics. 
The different semantics aren't yet implemented in D2 but they are most 
useful to determine whether I can, for example, decide whether to send a 
slice (to in parameters) or a copy (to const parameters).

>> I myself stay out of 'ref' and 'out' params since they do not yet 
>> optimize and add quite a lot of overhead making temporary "safe" 
>> copies of the data.
> 
> I understand the problem behind not optimizing  (inline), but I'm not 
> sure what you mean by making temporary "safe" copies.

Right now the compiler makes a temporary copy of referenced parameters 
on the stack, calls the function with a pointer to the stack copy, and 
once the function returns copies the modified temporary back to its 
original location. This is quite considerable overhead.

>> Also 'scope' params have a meaning, when a delegate parameter is 
>> declared as scope, it allows a closure to use stack storage instead of 
>> the usual heap storage.
> 
> yes, but in the context of an 'in' parameter, most of the time you are 
> not passing a delegate using in, so scope doesn't mean much there.

The implied 'scope' in 'in' has no effect yet due to a current compiler 
bug. You have to explicitly use 'scope' when declaring delegate 
parameters. Just like the 'in' vs 'const' have different semantics, 'in' 
vs plain 'scope' also have different semantics, which should get fixed soon.

For example, consider the following:

void Foo(scope delegate() bar) { bar(); }
void Foo2(delegate() bar) { bar(); }

// This method uses stack storage, the implied scope in 'in' should also 
work here, but is bugged right now so explicit 'scope' is needed
void Test() {
     void Bar() {}
     Foo(&Bar);
}

// This method uses heap storage allocated on the GC through _d_allocmemory
// Notice how the only difference is the 'scope' qualifier of Foo2()
void Test2() {
     void Bar() {}
     Foo2(&Bar);
}

Jeremie


More information about the Digitalmars-d-learn mailing list