ref arguments

Steven Schveighoffer schveiguy at yahoo.com
Mon Sep 21 11:50:37 PDT 2009


On Mon, 21 Sep 2009 14:28:09 -0400, Jeremie Pelletier <jeremiep at gmail.com>  
wrote:

> Steven Schveighoffer wrote:
>> On Mon, 21 Sep 2009 12:23:46 -0400, Jeremie Pelletier  
>> <jeremiep at gmail.com> wrote:
>>>
>>> '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).

Yes, that would be useful if it was enforced.  But it's not, so it's not  
useful.  Unless you trust the compiler in your head :)

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

Are you sure this is true?  I don't have a d2 compiler right now, but that  
sounds like a *huge* step in the wrong direction.  D1 does not do this  
(tested dmd 1.046).

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

Yes, I understand the reasoning for scope delegates.  My point was that
1. scope for non-delegate parameters is currently a noop
2. const does not make any sense for a delegate.

So arguing that the 'scope' part of 'in' is useful for delegates is  
currently a moot point.  I guess you could use it as a quicker way to type  
scope or const, but it currently doesn't have any different use than just  
typing 'scope' (for delegates) or 'const' (for other types).

>
> 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);
> }

it's still incomplete.  For example, this still allocates a closure on the  
heap:

void Bar() {}
auto x = &Bar;
Foo2(x);

I think scope will have to become a type-modifier before it is a complete  
solution.

-Steve


More information about the Digitalmars-d-learn mailing list