"ref const" parameters in functions
Steven Schveighoffer
schveiguy at yahoo.com
Mon Apr 2 13:48:56 PDT 2012
On Mon, 02 Apr 2012 00:23:50 -0400, Jonathan M Davis <jmdavisProg at gmx.com>
wrote:
> No. It's not. It's a temporary, and temporaries are almost always
> rvalues. The
> sole (and very bizarre) exception is struct literals (e.g. ABC(20) is
> currently considered an lvalue). It results in the bizarre situation
> that a
> function which takes a const ref will work with ABC(20) but won't work
> with a
> function that returns ABC(20). It's a point of debate and may be
> changed, in
> which case ABC(20) would not be an lvalue anymore. But regardless, the
> result
> of operations such as + are _always_ rvalues.
Also, 'this' is passed as a reference, even though it could be an rvalue.
This makes for some WTF cases. For example:
struct S
{
int x;
S opBinary(string op)(ref const S other) const { return S(other.x + x);}
}
void main()
{
auto s = S(1);
auto s2 = S(2);
auto s3 = (s + s2) + s2; // ok
auto s4 = s2 + (s + s2); // error
}
I think the current state of affairs is far from ideal, and really should
get some more attention, but it's quite low on the priority list.
-Steve
>
> Normally, the only items that are lvalues are variables and return values
> which are ref. The result of a function or operator such as + is most
> definitely _not_ an lvalue, since you can't return their results by ref.
> It's a
> classic example on an rvalue.
>
> If you want to avoid making copies, then you're going to need to make
> your
> parameters auto ref (and hope that the compiler decides that making a
> copy is
> more expensive - I don't know how it decides that) or make them const
> ref and
> use lvalues - and using lvalues generally means creating explicit
> variables
> and _not_ using temporaries. So, your long expression with + and * would
> have
> to be changed to use += and *=.
>
>> when I draw to the screen 50000 graphical objects by OpenGL, it
>> uses a matrices operation via D-language structures (uses all
>> math operators and makes some matrices operations for every
>> graphical object on the scene for each time), the unnecessary
>> copyes of it(matrices) is very bad for engine performance.
>
> Sure, if you have large structs, making a lot of copies of them can be
> expensive. But to avoid that, you're going to have to avoid coding in a
> way
> which creates temporaries, and expressions like
>
> (abc1+abc2*20.0)+(abc1*abc2+abc1*20.0)
>
> will _always_ create temporaries. The classic, arithmetic operators are
> classic examples of functions which create temporaries (all of which are
> rvalues). So, you can't code that way and expect to avoid temporaries.
>
> - Jonathan M Davis
More information about the Digitalmars-d-learn
mailing list