Const ref and rvalues again...

martin kinke at libero.it
Tue Nov 13 06:07:41 PST 2012


On Tuesday, 13 November 2012 at 08:34:19 UTC, luka8088 wrote:
>> Your proposal isn't really related to this thread's topic
>
> Um, "Const ref and rvalues again", I suggest it to be the 
> default behavior, how is this not related ?

The topic here is binding rvalues to (const) ref parameters. You, 
on the other hand, are suggesting to flip the constness of 
by-value parameters (int => val/mutable int, const int => int), 
which affects both rvalues and lvalues (no difference between 
them) and only by-value parameters.

> Yes, you understood correctly:
> void f (const ref int x, int y, ref int z); =>
> void f (int x, val int y, ref int z);
>
> The point here is to make "We need a way for a function to 
> declare that it doesn't want it's argument to be copied, but it 
> also doesn't care whether the argument is an rvalue or an 
> lvalue. " a default behavior.

So now tell me why argument x wouldn't be copied. It's passed by 
value, so of course it is copied (lvalues)/moved (rvalues) just 
as it is now. The only difference is that the parameter won't be 
modified by f().

I guess what you furthermore implicate is that you'd expect the 
compiler to automatically pass appropriate arguments to such 
parameters by reference to avoid copying (for large structs or 
structs with non-trivial copy constructors). Such a (handy!) 
optimization is sadly not possible due to aliasing issues, e.g.:

int foo(ref int dst, const int src)
{
     dst = 2*src;
     return src;
}
// "optimized" foo():
int bar(ref int dst, const ref int src)
{
     dst = 2*src;
     return src;
}

int i = 1;
assert(foo(i, i) == 1 && i == 2); // okay
i = 1;
assert(bar(i, i) == 2 && i == 2); // wtf?!
// the const src parameter is actually modified since the
// original argument i is also used as mutable dst parameter!

> Would it ? How many functions actually change their non ref/out 
> arguments ? Can you point out any existing public code that 
> would be broken ?

I don't want to look for examples in Phobos etc. as it should be 
trivial to imagine cases such as:

void bla(float x)
{
     // restrict x to safe range [0,1]
     x = max(0, min(1, x));
}


More information about the Digitalmars-d mailing list