digitalmars.D.learn - lvalue method
- Benjamin Thaut (23/23) Oct 08 2010 Hi, I'm writing a vec4 math struct and I have a method of which the
- Stanislav Blinov (13/39) Oct 08 2010 If you need to normalize vector inplace, then your Normalize() shouldn't...
- Simen kjaeraas (9/29) Oct 08 2010 Will simply not compile.
- Lars T. Kyllingstad (16/37) Oct 08 2010 The compiler shouldn't even accept this. When I try a similar thing, DM...
- Benjamin Thaut (28/65) Oct 08 2010 All this was only to get it to return a lvalue. I need a lvalue to be
- Steven Schveighoffer (15/92) Oct 08 2010 The correct way is to use auto ref as the parameter:
- Simen kjaeraas (6/13) Oct 08 2010 It doesn't, no. I'm not even sure it's scheduled for inclusion.
- Steven Schveighoffer (10/23) Oct 08 2010 Andrei, I thought this was planned?
- BCS (9/64) Oct 13 2010 Does Cross take a non const ref? I wouldn't think it would need a mutabl...
- Benjamin Thaut (10/72) Oct 13 2010 Well it is basically a 3D vector, but it has 4 elements because it is
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? ref vec4 Normalize() const { vec4* temp = new vec4; ... return *temp; } //ugly, don't want to allocate anything on the heap auto ref vec4 Normalize() const { vec4 temp; ... return temp; } //will this lead to a segfault? Or do I need to do it totaly in some other way? -- Kind Regards Benjamin Thaut
Oct 08 2010
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? ref vec4 Normalize() const { vec4* temp = new vec4; ... return *temp; } //ugly, don't want to allocate anything on the heap auto ref vec4 Normalize() const { vec4 temp; ... return temp; } //will this lead to a segfault? Or do I need to do it totaly in some other way?If you need to normalize vector inplace, then your Normalize() shouldn't be const: ref vec4 Normalize() { // code return this; } If you want to return a normalized copy of vector, the you don't need ref: vec4 Normalize() const { vec4 temp; //... return temp; }
Oct 08 2010
Benjamin Thaut <code benjamin-thaut.de> 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?Will simply not compile. (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 heapThis will work.auto ref vec4 Normalize() const { vec4 temp; ... return temp; } //will this lead to a segfault?The compiler will conclude that temp cannot be returned as ref, and thus do a value return.Or do I need to do it totaly in some other way?Don't know. Why does it have to be an lvalue? -- Simen
Oct 08 2010
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 heapThis 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
Oct 08 2010
Am 08.10.2010 11:13, schrieb Lars T. Kyllingstad:On Fri, 08 Oct 2010 09:33:22 +0200, Benjamin Thaut wrote: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 ThautHi, 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 heapThis 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
Oct 08 2010
On Fri, 08 Oct 2010 09:26:19 -0400, Benjamin Thaut <code benjamin-thaut.de> wrote:Am 08.10.2010 11:13, schrieb Lars T. Kyllingstad:The correct way is to use auto ref as the parameter: struct vec4 { ... vec4 Normalize(auto ref const(vec4) param) {...} } But AFAIK, this doesn't really work. What it *should* do is generate two versions of Normalize, one which passes param by reference for lvalues, and one that passes by value for rvalues. Passing rvalues by value is more efficient and less problematic than passing by reference, since the value is already located on the stack, and there is no need to make a copy. -SteveOn Fri, 08 Oct 2010 09:33:22 +0200, Benjamin Thaut wrote: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.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 heapThis 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
Oct 08 2010
Steven Schveighoffer <schveiguy yahoo.com> wrote:The correct way is to use auto ref as the parameter: struct vec4 { ... vec4 Normalize(auto ref const(vec4) param) {...} } But AFAIK, this doesn't really work.It doesn't, no. I'm not even sure it's scheduled for inclusion. work, so the only current solution is to not use ref. -- Simen
Oct 08 2010
On Fri, 08 Oct 2010 09:51:59 -0400, Simen kjaeraas <simen.kjaras gmail.com> wrote:Steven Schveighoffer <schveiguy yahoo.com> wrote:Andrei, I thought this was planned?The correct way is to use auto ref as the parameter: struct vec4 { ... vec4 Normalize(auto ref const(vec4) param) {...} } But AFAIK, this doesn't really work.It doesn't, no. I'm not even sure it's scheduled for inclusion.work, so the only current solution is to not use ref.Bummer. At least rvalues will be as fast as possible, and it will work as a temporary solution. FWIW, I don't consider duplicating a function to be a good solution, we can do better. But don't try doing opEquals without ref const, because the compiler won't allow it :) -Steve
Oct 08 2010
Hello Benjamin,Am 08.10.2010 11:13, schrieb Lars T. Kyllingstad:Does Cross take a non const ref? I wouldn't think it would need a mutable vector. If it's not const, that's your problem. Figure out how to make it const (you "should" be able to as long as no mutation is being done) and this problem should go away. Also, how the heck do you define cross product for 2 4D vectors? I know how to do 2x3D and I can guess how to do 3x4D. -- ... <IXOYE><On Fri, 08 Oct 2010 09:33:22 +0200, Benjamin Thaut wrote: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.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 heapThis 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
Oct 13 2010
Am 13.10.2010 15:50, schrieb BCS:Hello Benjamin,Well it is basically a 3D vector, but it has 4 elements because it is used in computer grahpics that way and for SSE you need a 128bit struct. I tried with taking cost ref, but that doesn't work out at all, there are many places where it complains that it can not convert to const ref. Kind Regards Benjamin Thaut -- Kind Regards Benjamin ThautAm 08.10.2010 11:13, schrieb Lars T. Kyllingstad:Does Cross take a non const ref? I wouldn't think it would need a mutable vector. If it's not const, that's your problem. Figure out how to make it const (you "should" be able to as long as no mutation is being done) and this problem should go away. Also, how the heck do you define cross product for 2 4D vectors? I know how to do 2x3D and I can guess how to do 3x4D.On Fri, 08 Oct 2010 09:33:22 +0200, Benjamin Thaut wrote: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.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 heapThis 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
Oct 13 2010