The liabilities of binding rvalues to ref
Steven Schveighoffer
schveiguy at yahoo.com
Thu May 9 18:53:05 PDT 2013
On Thu, 09 May 2013 20:38:47 -0400, Manu <turkeyman at gmail.com> wrote:
> What were the arguments again against ref const()? You're talking about
> making it clear that the function isn't planning on mutating the given
> rvalue...
> I understand that const is stronger than C++, but is it actually a
> deal-breaker? It's the most logical fit here.
the counter-argument goes something like this:
struct VeryLarge
{
int[10] buffer;
VeryLarge *next;
}
So let's say you build a VeryLarge and return it, on the stack. Return by
value.
VeryLarge buildOne(someArguments);
OK, you now want to assign it to a property:
class X
{
private VeryLarge _vl;
@property void vl(ref VeryLarge otherValue) { _vl = otherValue;}
}
X x = new X;
x.vl = buildOne(...);
If we make otherValue const, then we can't assign because of the
indirection.
It's a tenuous argument, and I may not have made it in the best way, but
the bottom line is that const is overly restrictive in this case. We're
passing by ref because we don't want to incur the copy penalty *twice*.
If we make it const, we've added an incorrect restriction.
The solution, ironically, is to take VeryLarge by value as an overload.
This will simply do a move, and since it's already on the stack, no extra
copy is made.
So we NEED it to be mutable, and we don't want to restrict ourselves from
accepting rvalues.
So the above works fine as ref, for r and l values, because we are just
trying to copy the data. It's when you specifically are passing by ref to
modify the data that you want to reject rvalues.
As the original post in this thread pointed out, it's the way a library
can alter another author's intention that causes problems.
I have another idea, but I need to put it at the top so it's not lost :)
-Steve
More information about the Digitalmars-d
mailing list