"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