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