On 13.11.2012 15:07, martin wrote:
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));
}

I see, you are correct, if it is not copied then it can be changed before function finished through some other references hence it must be copied.

Reply via email to