lvalue method

Benjamin Thaut code at benjamin-thaut.de
Fri Oct 8 06:26:19 PDT 2010


Am 08.10.2010 11:13, schrieb Lars T. Kyllingstad:
> On Fri, 08 Oct 2010 09:33:22 +0200, Benjamin Thaut wrote:
>
>> Hi, I'm writing a vec4 math struct and I have a method of which the
>> return value has to be a lvalue so I wonder which is the correct way to
>> do this:
>>
>> vec4 Normalize() const { ... } //won't work, not a lvalue
>>
>> ref vec4 Normalize() const {
>>     vec4 temp;
>>     ...
>>     return temp;
>> } //will this lead to a segfault or not?
>
> The compiler shouldn't even accept this.  When I try a similar thing, DMD
> says "Error: escaping reference to local variable temp".
>
>
>> ref vec4 Normalize() const {
>>     vec4* temp = new vec4;
>>     ...
>>     return *temp;
>> } //ugly, don't want to allocate anything on the heap
>
> This would work, since the variable is no longer on the stack and thus
> survives the return of the function.
>
>
>> auto ref vec4 Normalize() const {
>>     vec4 temp;
>>     ...
>>     return temp;
>> } //will this lead to a segfault?
>
> Well, that should compile, but it doesn't work the way you want.  'auto
> ref' means that the function returns by ref if the return expression is
> an lvalue *and it would not be a reference to a local or a parameter*.
> So for this example, your function would return by value, not by ref.
>
>
>> Or do I need to do it totaly in some other way?
>
> Yes, you do. :)  You are trying to create a variable on the stack, and
> return it by reference.  The problem is that when the function returns,
> its stack frame (the memory occupied by the function's local variables)
> is "released".  At that point the variable doesn't exist anymore, and any
> reference to it would be invalid.
>
> -Lars

All this was only to get it to return a lvalue. I need a lvalue to be 
able to do stuff like this.

vec4 v1 = vec4(...);
vec4 v2 = vec4(...);
vec4 v3 = v1.Cross(v2.Normalize()).Normalize();

Here it complained that v2.Normalize is not a lvalue, for whatever reason.

I'm trying to make my matrix class work even if it is const to prevent 
it from coyping 16 floats everytime I pass it to a function.

mat4 opMul(ref const(mat4) m1, ref const(mat4) m2) const {
   ...
}

I tried many things, but it turned out that basically I have to get rid 
of all the consts and let it copy the matrixes everytime.

Because either it would tell me can not call 
opMul((mat4)const,(mat4)const) const with (mat4)const, (mat4)const <- I 
think this is because of the ref.

Or it would tell me opMul(...) is not a lvalue if I try it to use it 
like this

vec4 v1,v2;
mat4 m;

vec4 res = (v1 - m * v2);

I'm coming form C++ so is it the correct way to overload such operators 
without const at all? Because obviously I don't want it to copy 
unneccessarily.

-- 
Kind Regards
Benjamin Thaut


More information about the Digitalmars-d-learn mailing list