Const ref and rvalues again...

martin kinke at libero.it
Thu Nov 8 13:16:08 PST 2012


On Thursday, 8 November 2012 at 20:15:51 UTC, Dmitry Olshansky 
wrote:
> The scope. It's all about getting the correct scope, destructor 
> call and you know, the works. Preferably it can inject it 
> inside temporary scope.
>
> typeof(foo(...)) r = void;
> {
> someRef = SomeResource(x, y, ..);
> r = foo(someRef); // should in fact construct in place not 
> assign
> }
>
> I suspect this is hackable to be more clean inside of the 
> compiler but not in terms of a re-write.

Right, I forgot the scope for a moment. I'd illustrate the rvalue 
=> (const) ref binding to a novice language user as follows:

T   const_foo(  in ref int x);
T mutable_foo(auto ref int x);

int bar() { return 5; }

T result;

result = const_foo(bar());
/* expanded to:
{
     immutable int tmp = bar(); // avoidable for literals
     result = const_foo(tmp);
} // destruction of tmp
*/

result = mutable_foo(bar());
/* expanded to:
{
     int tmp = bar();
     result = mutable_foo(tmp);
} // destruction of tmp
*/

> I'd rather restrict it to 'auto ref' thingie. Though 'in auto 
> ref' sounds outright silly.
> Simply put const ref implies that callee can save a pointer to 
> it somewhere (it's l-value). The same risk is with 'auto ref' 
> but at least there an explicitly written 'disclaimer' by the 
> author of accepting temporary stuff.

'in ref' as opposed to 'const ref' should disallow this escaping 
issue we've already tackled in this thread, but I'm not sure if 
it is already/correctly implemented. Anyway, this issue also 
arises with (short-lived) local lvalues at the caller site:

foreach (i; 0 .. 10)
{
     int scopedLvalue = i + 2;
     foo(scopedLvalue); // passed by ref
} // scopedLvalue is gone

> In the ideal world name 'auto ref' would be shorter, logical 
> and more to the point but we have what we have.

+1, but I don't have a better proposal anyway. ;)

> I think that function plucked with auto ref is a enough 
> indication that author is fine with passing to it mutable 
> r-values and not seeing changes outside and related blah-blah.

Agreed.

> Also certain stuff can't be properly bitwise const because of 
> C-calls and what not. Logical const is the correct term but in 
> the D world it's simply mutable.

As you know, I'd definitely allow rvalues to be bound to const 
ref parameters as alternative (that would also be useful for a 
lot of existing code). People who generally don't use const 
(Timon Gehr? :)) are free to only use 'auto ref', I'm most likely 
only going to use 'in ref', and there will certainly be people 
using both. Sounds like a really good compromise to me.

> I'd say that even for templates the speed argument is mostly 
> defeated by the bloat argument. But that's probably only me.

I haven't performed any benchmarks, but I tend to agree with you, 
especially since multiple 'auto ref' parameters lead to 
exponential bloating. I could definitely do without a special 
role for templates, which would further simplify things 
considerably. If performance is really that critical, an explicit 
pass-by-value (move) overload for rvalues ought to be enough 
flexibility imo.


More information about the Digitalmars-d mailing list