On 05/12/2012 12:13 PM, Jonathan M Davis wrote:
On Saturday, May 12, 2012 13:03:26 Manu wrote:
On 12 May 2012 12:37, Jonathan M Davis<jmdavisp...@gmx.com>  wrote:
On Saturday, May 12, 2012 11:26:37 Timon Gehr wrote:
On 05/12/2012 10:13 AM, Manu wrote:
On 11 May 2012 21:28, Mehrdad<wfunct...@hotmail.com

<mailto:wfunct...@hotmail.com>>  wrote:
     Yes, I agree, but consider that D users should NOT have to work

with

     pointers to do something so basic

I'd like to think this were true, but the fact that 'ref' barely works
makes this almost immediately false when trying to write any

non-trivial

program.

It depends on the coding style.

I rarely end up passing by either ref or pointer, and the only issues that
I've ever had with ref relate to the fact that you can't pass it rvalues.
Obviously both pointers and ref have their uses, but I'd definitely have
to
concur that it depends on your coding style and what you're doing. Also, I
really don't know what's wrong with ref such that anyone could say that it
"barely works" other than the issues with rvalues and functions which take
ref
or const ref.

struct X
{
int i;

X opBinary(string op)(const ref X b) if(op == "+") { return X(i + b.i); }
ref X opOpAssign(string op)(const ref X b) if(op == "+") { i += b.i; return
this; }
...etc
}

ref X func(ref X x)
{
return x;
}

bool maybe()
{
return (time()&  1) != 0;
}

void test()
{
X a,b,c;
X v[];

func(a); // this is basically the only expression that works
X t = a + (b + c); // fail
a += b + c; // fail
ref X t = func(a); // fail
func(a + b); // fail
func(maybe() ? a : b); // this generates bad code:
http://forum.dlang.org/thread/cnwpmhihmckpjhlas...@forum.dlang.org
ref X t = v[some + complex * (expression + that_i_dont_want_to_repeat())];
// fail

foreach(i; 0..10)
{
ref X t = v[some + expression * involving - i]; // fail
}
}

Just a couple of extremely common usage patterns that come to mind. I'm
sure there are many more...

So, basically it's just the issue with neither ref nor const ref taking
lvalues. If you duplicate the functions (or use auto ref if they're templated
functions), then it's not an issue. It sucks to have to duplicate stuff, but
ref works just fine as long as you don't assume that it's going to allow you to
pass rvalues to it. Personally, I almost always just have functions take
structs by value, so it's a non-issue except for stuff like opEquals, which
requires const ref (for at least one overload anyway).

However, given the ridiculousness of having to duplicate functions to make ref
usuable for any case where you're specifically trying to avoid a copy rather
than use it to pass a value out, Andrei and Walter are looking at making ref
work with rvalues. They just have to sort out how to avoid the issues that C++
has due to allow const&  to take rvalues (which is why const ref in D doesn't
currently take rvalues). So, there's a good chance that the situation will
improve considerably sometime soon.

- Jonathan M Davis

I don't see why 'const' should make a difference there anyway. It is completely orthogonal. It could be argued that the callee might assume that his changes will be visible for the caller, but if the point of passing an rvalue by reference is to gain performance, forbidding the callee to use it as scratch space is just ridiculous.

Reply via email to