September 1, 2016 at 7:46 pm #3592
I have an offset I want to add to the X component of a vector. Can someone tell me why this doesn’t work:Monkey1TargetVector.X+=offset
But this does:Monkey1TargetVector = New Vec2f(TargetVector.X+offset, TargetVector.Y)
I like the first version, but I don’t know why it doesn’t work.September 1, 2016 at 7:50 pm #3593
There are a number of reasons why this may not work – what error are you getting?September 1, 2016 at 7:57 pm #3594
No error. I’m getting no result. It looks like nothing happens.
Could it happen because here TargetVector is a Property in a base class? It returns a Vec2f.
EDIT: Yes it does! If I do this, it works:Monkey123local vec:= TargetVectorvec.X+=offsetTargetVector = vec
That doesn’t sound right to me.September 1, 2016 at 8:30 pm #3595
Yep, it’s because it’s a property returning a struct.
When a property (or method, or function, or anything ‘callable’) returns a struct, it always returns a copy of the struct – that’s just how structs work, and is what really allows them to be so lightweight and require no memory management.
So the TargetVector property is only returning a ‘temporary’ copy of the Vec2f you’re interested in, and modifying this copy is effectively a NOP. All you can really do with this copy is read it – think of it being stored in a ‘hidden’ local…
The compiler does in fact detect writes to fields of temporary copies like this, ie: this generates a ‘not assignable’ error:
TargetVector.x+=10 ‘note: lowercase ‘x’ – ie: just the field!
But in the case where you’re assigning ‘x’ via the ‘X’ property, the compiler doesn’t/can’t know that the ‘X’ property assigns something to Self and doesn’t even try to detect this.
Getting this to generate an error is complicated. Either the user would have to mark properties/methods as ‘Const’ or not, ala c++, which is not a lot of fun, or the compiler has to automatically detect which properties/methods modify ‘Self’, which is trickier than it may sound. Just because X() might not write a field, it might invoke another method that (ultimately) *does* etc. In fact, thanks to functions pointers it may be logically impossible.September 2, 2016 at 2:49 am #3598
I think, properties X/Y are unnecessary in vec2, need to remove them.
IMO, If there is no logic in setter/getter then we should not use properties at all.September 2, 2016 at 6:32 am #3601
Good explanation Mark. Thanks! Learn something every day. 🙂
@nerobot: We need access to the private fields. We have no use of a vector where there is no access to the x and y private fields. Knowing a struct is always a copy is good enough for me.September 2, 2016 at 9:04 am #3606
Actually, I sort of agree with nerobot here – but not completely!
‘x’ and ‘y’ are already available as public fields – I consider this OK *because* you’re (almost) always working with your own copy – and perhaps having the setters just confuses things as it prevents the compiler catching situations like the above?
On the other hand, setters that do more than just set one field can be useful – eg: the ‘TopRight’ (which sets max.x and min.y) setter for Rect, so perhaps there’s not really a ‘right’ answer to this problem.
I did actually spend a fair bit of time trying to come up with solutions for this because I knew it would trip people up, but I couldn’t think of anything that wasn’t going to either take ages to implement (and possibly not even work) or involve adding a bunch of weird ‘Const’ stuff to the language.
But I’m happy my explanation makes sense!September 2, 2016 at 10:42 am #3608
When I experimented optimization I saw that struct properties are slower than fields.
And I thought the same. in vec2, X and Y properties shouldn’t be there because some people will slow down their loops by choosing (unuselfull)properties instead of field in their calculation.
You must be logged in to reply to this topic.