On Mon, 02 Apr 2012 00:23:50 -0400, Jonathan M Davis <jmdavisp...@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

Reply via email to