Re: A question about DbC
On Friday 08 October 2010 20:16:10 bearophile wrote: > This is a simple D2 class that uses Contracts: > > > import std.c.stdio: printf; > > class Car { > int speed = 0; > > invariant() { > printf("Car invariant: %d\n", speed); > assert(speed >= 0); > } > > this() { > printf("Car constructor: %d\n", speed); > speed = 0; > } > > void setSpeed(int kmph) > in { > printf("Car.setSpeed precondition: %d\n", kmph); > assert(kmph >= 0); > } out { > printf("Car.setSpeed postcondition: %d\n", speed); > assert(speed == kmph); > } body { > printf("Car.setSpeed body\n"); > speed = kmph; > } > } > > void main() { > auto c = new Car(); > c.setSpeed(10); > } > > > This is the output of the program, dmd 2.049: > > Car constructor: 0 > Car invariant: 0 > Car.setSpeed precondition: 10 > Car invariant: 0 > Car.setSpeed body > Car invariant: 10 > Car.setSpeed postcondition: 10 > > Is it correct? I think the invariant needs to run before the precondition > and after the postcondition. Why? The invariant only really needs to be run after each public function runs. It could be before or after the postcondition. Both the postcondition and invariant need to be true and they're completely independent, so they could be run in either order. What's odder is that the invariant is run after the precondition. That shouldn't be necessary, since any changes to the object would have been verifed after the last time that a public member function was called. Maybe it's because of the possibility of member variables being altered because they were returned by reference or because of public member variables having possibly been altered. Regardless, since the postcondition and invariant are indepedent, it shouldn't matter which order they run in - particularly since they are essentially pure, even if purity is not enforced for them (that is, unless you're doing something stupid, neither of them will alter the state of the object, so they could be run in either order). - Jonathan M Davis
A question about DbC
This is a simple D2 class that uses Contracts: import std.c.stdio: printf; class Car { int speed = 0; invariant() { printf("Car invariant: %d\n", speed); assert(speed >= 0); } this() { printf("Car constructor: %d\n", speed); speed = 0; } void setSpeed(int kmph) in { printf("Car.setSpeed precondition: %d\n", kmph); assert(kmph >= 0); } out { printf("Car.setSpeed postcondition: %d\n", speed); assert(speed == kmph); } body { printf("Car.setSpeed body\n"); speed = kmph; } } void main() { auto c = new Car(); c.setSpeed(10); } This is the output of the program, dmd 2.049: Car constructor: 0 Car invariant: 0 Car.setSpeed precondition: 10 Car invariant: 0 Car.setSpeed body Car invariant: 10 Car.setSpeed postcondition: 10 Is it correct? I think the invariant needs to run before the precondition and after the postcondition. Bye, bearophile
Re: ditto in DDoc
On Friday, October 08, 2010 15:17:13 bearophile wrote: > Jonathan M Davis: > > It's the past participle of the Italian word dire (to say) > > It was, a long time ago. Today it's "detto". > > Bye, > bearophile Good to know. I was just going by what Merriam Webster had to say on that one. I know French but not Italian. - Jonathan M Davis
Re: ditto in DDoc
On Sat, 09 Oct 2010 01:22:33 +0400, Tomek Sowiński wrote: More of an English question... dunno <- don't know ditto <- ? Ditto is used to indicate that something already said is applicable a second time. In documentation, "ditto" means that previous comment also applies here. Here is an example: /// helper function void doStuff(); /// ditto (i.e. helper function) void doOtherStuff();
Re: ditto in DDoc
Jonathan M Davis: > It's the past participle of the Italian word dire (to say) It was, a long time ago. Today it's "detto". Bye, bearophile
Re: ditto in DDoc
On Friday, October 08, 2010 14:22:33 Tomek Sowiński wrote: > More of an English question... > dunno <- don't know > ditto <- ? It's a word in and of itself, not the shortening or butchering of another word. According to merriam-webster.com ( http://www.merriam- webster.com/dictionary/ditto ), it comes from Italian. It's the past participle of the Italian word dire (to say) - which also happens to be the French word for to say, but French has a different past participle. - Jonathan M Davis
Re: ditto in DDoc
On Fri, 08 Oct 2010 16:22:33 -0500, Tomek Sowiński wrote: More of an English question... dunno <- don't know ditto <- ? http://en.wiktionary.org/wiki/ditto ditto (plural dittos) 1. That which was stated before, the aforesaid, the above, the same. 2. (informal) A duplicate or copy of a document. -- Yao G.
Re: std.regex character consumption
On Friday, October 08, 2010 14:13:36 petevi...@yahoo.com.au wrote: > I've been running into a few problems with regular expressions in D. One > of the issues I've had recently is matching strings with non ascii > characters. As an example: > > auto re = regex( `(.*)\.txt`, "i" ); > re.printProgram(); > auto m = match( "bà.txt", re ); > writefln( "'%s'", m.captures[1] ); > > When I run this I get the following error: > > dchar decode(in char[], ref size_t): Invalid UTF-8 sequence [160 46 116 > 120] around index 0 > printProgram() > 0: REparen len=1 n=0, pc=>10 > 9: REanystar > 10: REistring x4, '.txt' > 19: REend > > While investigating the cause, I noticed that during execution of many > of the regex instructions (e.g. REanystar), the source is advanced with: > > src++; > > However in other cases (REanychar), it is advanced with: > > src += std.utf.stride(input, src); > > I found that by replacing the code REanystar with stride, the code > worked as expected. Although I can't claim to have a solid understanding > of the code, it seems to me that most of the cases of src++ should be > using stride instead. > > Is this correct, or have I made some silly mistake and got completely > the wrong end of the stick? Well, without looking at the code, I can't say for certain what's going on, but using ++ with chars or wchars is definitely wrong in virtually all cases. stride() will actually go to the next code point, while ++ will just go to the next code unit, which could be in the middle of a code point. - Jonathan M Davis
ditto in DDoc
More of an English question... dunno <- don't know ditto <- ? -- Tomek
std.regex character consumption
I've been running into a few problems with regular expressions in D. One of the issues I've had recently is matching strings with non ascii characters. As an example: auto re = regex( `(.*)\.txt`, "i" ); re.printProgram(); auto m = match( "bà.txt", re ); writefln( "'%s'", m.captures[1] ); When I run this I get the following error: dchar decode(in char[], ref size_t): Invalid UTF-8 sequence [160 46 116 120] around index 0 printProgram() 0:REparen len=1 n=0, pc=>10 9:REanystar 10:REistring x4, '.txt' 19:REend While investigating the cause, I noticed that during execution of many of the regex instructions (e.g. REanystar), the source is advanced with: src++; However in other cases (REanychar), it is advanced with: src += std.utf.stride(input, src); I found that by replacing the code REanystar with stride, the code worked as expected. Although I can't claim to have a solid understanding of the code, it seems to me that most of the cases of src++ should be using stride instead. Is this correct, or have I made some silly mistake and got completely the wrong end of the stick?
Re: [D1][expressions] Order Of Evaluation
== Quote from Denis Koroskin (2kor...@gmail.com)'s article > On Fri, 08 Oct 2010 18:49:36 +0400, %u wrote: > > /The following binary expressions are evaluated in an > > implementation-defined > > order: > > AssignExpression/../AddExpression/ > > > > /It is an error to depend on order of evaluation when it is not > > specified./ > > > > That makes this an error!? > > > > y = x + 1; > > > > Am I being paranoid or should I be adding more brackets? > Assignment has higher precedence that addition so your code has no errors. You probably mean that the other way around ;) But you are right, I am confusing precedence and associativity. The expressions page reads like there are only two levels of precedence, but it only says anyting about the associativity. A quick search on precedence shows that the C precedence rules apply. > However, the following one does: > int x = 1; > int y = (x = 2) + x; > because "x" and "x = 2" has same precedence and thus may be evaluated in > any order. > Stay away from such code and you should be fine. I never assign within assignments :)
Re: [D1][expressions] Order Of Evaluation
On Fri, 08 Oct 2010 18:49:36 +0400, %u wrote: /The following binary expressions are evaluated in an implementation-defined order: AssignExpression/../AddExpression/ /It is an error to depend on order of evaluation when it is not specified./ That makes this an error!? y = x + 1; Am I being paranoid or should I be adding more brackets? Assignment has higher precedence that addition so your code has no errors. However, the following one does: int x = 1; int y = (x = 2) + x; because "x" and "x = 2" has same precedence and thus may be evaluated in any order. Stay away from such code and you should be fine.
Re: [D1][expressions] Order Of Evaluation
%u: > That makes this an error!? > > y = x + 1; > > Am I being paranoid or should I be adding more brackets? I presume this doesn't need other brackets. And Walter has two or three times stated that he wants to eventually define the order of evaluation in D (as C#/Java), I hope this will happen. Bye, bearophile
Re: Destruction Sequence: module and classes defined within
Lars T. Kyllingstad wrote: > On Tue, 05 Oct 2010 23:25:36 +0200, vano wrote: > >> The code below: >> module used; >> >> import std.stdio; >> >> class ClassA { >> this() { writeln("A ctor"); } >> ~this() { writeln("A dtor"); } >> } >> >> static this() { writeln("used.sctor"); } static ~this() { >> writeln("used.sdtor"); } >> >> void main() { >> auto a = new ClassA(); >> } >> produces the following output (DMD v2.049): >> used.sctor >> A ctor >> used.sdtor >> A dtor >> >> The question is: should the module be allowed to be unloaded before all >> module-level objects/structures are destructed/unloaded? > > > I'm no expert on this, but I think it has to be that way. Consider this: > > class Foo { ... } > Foo foo; > > static this() > { > foo = new Foo; > } > > static ~this() > { > foo.doStuff(); > } > > So you see, if foo had already been destroyed and garbage collected, my > program would have crashed when the module static destructor was run. > Thus, I guess, running the garbage collector for the final time has to be > one of the last things done on program shutdown, after running all module > destructors. > > -Lars In this case however, foo is still referenced whereas in the original example 'a' is unreferenced after main exits. I could only find this in the spec: "The garbage collector is not guaranteed to run the destructor for all unreferenced objects." * >From reading the spec, I think that all one can conclude is that after main unreferenced objects may be finalized any time, or not at all. * http://www.digitalmars.com/d/2.0/class.html#Destructor
[D1][expressions] Order Of Evaluation
/The following binary expressions are evaluated in an implementation-defined order: AssignExpression/../AddExpression/ /It is an error to depend on order of evaluation when it is not specified./ That makes this an error!? y = x + 1; Am I being paranoid or should I be adding more brackets?
Re: lvalue method
On Fri, 08 Oct 2010 09:51:59 -0400, Simen kjaeraas wrote: Steven Schveighoffer 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. Andrei, I thought this was planned? Also, with bugzilla #4843, overloading ref/non-ref for structs don't 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
Re: lvalue method
Steven Schveighoffer 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. Also, with bugzilla #4843, overloading ref/non-ref for structs don't work, so the only current solution is to not use ref. -- Simen
Re: lvalue method
On Fri, 08 Oct 2010 09:26:19 -0400, Benjamin Thaut wrote: 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. 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. -Steve
Re: lvalue method
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
Re: question about property for built-in type
Thanks for the reply. I wonder are there any alternatives to achieve similar things for built-in types? I think this is very helpful for template function for built-in types.
Re: question about property for built-in type
08.10.2010 16:19, %u wrote: Hi, I'm learning D right now and got a question about property. I tried to add a property for built-in type like the following @property bool equalZero(double a) { return a == 0.0; } void main() { ... double x = 4.4; bool isXZero = x.equalZero; ... } but got an error message main.d(75): Error: no property 'equalZero' for type 'double' I tried similar thing with int[] and it works. Is that I did something wrong or property does not support built-in type like double, int, real, ...? Appreciate for your time and answer. What you're trying to do is utilize uniform function call syntax (foo(T) === T.foo()), but that is currently supported *only* for arrays. AFAIK it's going to be implemented at some point, but right now you will have to use equalZero(a) instead of a.equalZero.
Re: question about property for built-in type
On Fri, 08 Oct 2010 16:19:43 +0400, %u wrote: Hi, I'm learning D right now and got a question about property. I tried to add a property for built-in type like the following @property bool equalZero(double a) { return a == 0.0; } void main() { ... double x = 4.4; bool isXZero = x.equalZero; ... } but got an error message main.d(75): Error: no property 'equalZero' for type 'double' I tried similar thing with int[] and it works. Is that I did something wrong or property does not support built-in type like double, int, real, ...? Appreciate for your time and answer. Uniform Function Call syntax (i.e. a.b(c) -> b(a, c)) only works for arrays atm. This may or may not be changed in future.
question about property for built-in type
Hi, I'm learning D right now and got a question about property. I tried to add a property for built-in type like the following @property bool equalZero(double a) { return a == 0.0; } void main() { ... double x = 4.4; bool isXZero = x.equalZero; ... } but got an error message main.d(75): Error: no property 'equalZero' for type 'double' I tried similar thing with int[] and it works. Is that I did something wrong or property does not support built-in type like double, int, real, ...? Appreciate for your time and answer.
Re: lvalue method
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
Re: lvalue method
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? 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 heap This 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
Re: lvalue method
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; }
Re: Static problem
Bob Cowdery wrote: On 07/10/2010 21:32, Stanislav Blinov wrote: Steven Schveighoffer wrote: What I'd propose is either: 1) Create your own lock-free associative array (yup, reinvent the wheel to introduce AA to the world of 'shared') 2) In this small case it may seem best (though mind that often such cases do grow up to the point when you still need to rethink design): Make your associative array __gshared and perform synchronization by hand, i.e. create a static Mutex (from core.sync.mutex) variable and initialize it in your CRegistry's static ctor, and then enclose all access to associative array in synchronized(mutex) {} blocks. Maybe concurrent-programming-in-D guru may propose simpler solution, but I don't see another. FWIW, the classinfo of a class is an object, and as such can be used as sort of a global lock without having to use a static constructor: synchronized(this.classinfo) { } -Steve Thanks. To my shame, I repeatedly keep forgetting about this. Thanks for the suggestions. I'm keen to avoid locks as everything so far is message parsing and the system is real-time. Having lots of threads that all talk to each other I needed a place to keep the Tid's which is accessible to everyone. There is no conflict because the main thread creates all others and registers the Tid's. Once the threads go the registry is read only. Just setting __gshared makes the app work. This may not be good practice I know and I will come back to it when I have more time. I'm not sure how to use synchronized(this.classinfo). Is this in combination with __gshared to synchronise access at the method level. Is it like a wrapper that goes inside the method? bob Yeah, it's like this: static void register(E_PROC name, Tid tid) { synchronized(this.classinfo) { theRegistry[name] = tid; } } static Tid getTid(E_PROC name) { Tid* result; synchronized(this.classinfo) { result = name in TidRegistry; } //... } All Objects contain a 'monitor' which is a synchronization primitive. synchronized(some_object) { foo(); } is similar to { some_mutex.lock(); scope(exit) some_mutex.unlock(); // some code }
Re: Static problem
On 07/10/2010 21:32, Stanislav Blinov wrote: > Steven Schveighoffer wrote: > >>> What I'd propose is either: >>> 1) Create your own lock-free associative array (yup, reinvent the >>> wheel to introduce AA to the world of 'shared') >>> 2) In this small case it may seem best (though mind that often such >>> cases do grow up to the point when you still need to rethink design): >>> Make your associative array __gshared and perform synchronization by >>> hand, i.e. create a static Mutex (from core.sync.mutex) variable and >>> initialize it in your CRegistry's static ctor, and then enclose all >>> access to associative array in synchronized(mutex) {} blocks. >>> >>> Maybe concurrent-programming-in-D guru may propose simpler solution, >>> but I don't see another. >> >> FWIW, the classinfo of a class is an object, and as such can be used >> as sort of a global lock without having to use a static constructor: >> >> synchronized(this.classinfo) >> { >> >> } >> >> -Steve > > Thanks. To my shame, I repeatedly keep forgetting about this. Thanks for the suggestions. I'm keen to avoid locks as everything so far is message parsing and the system is real-time. Having lots of threads that all talk to each other I needed a place to keep the Tid's which is accessible to everyone. There is no conflict because the main thread creates all others and registers the Tid's. Once the threads go the registry is read only. Just setting __gshared makes the app work. This may not be good practice I know and I will come back to it when I have more time. I'm not sure how to use synchronized(this.classinfo). Is this in combination with __gshared to synchronise access at the method level. Is it like a wrapper that goes inside the method? bob
lvalue method
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