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