About Monkey 2 › Forums › Monkey 2 Programming Help › [solved] RVAL eval order
This topic contains 16 replies, has 5 voices, and was last updated by Mark Sibly 1 year ago.
-
AuthorPosts
-
February 7, 2017 at 3:12 pm #6981
This code display -5, then 5.
It seems that RVALMonkey
1-myStack.Pop()+myStack.Pop()is evaluated from rigth to left => -10+5 rather than -5+10.
The first Pop done is the one on rigth (rather than the one on left).
Is this a choice? With others languages (Lua,C,C#, Java…) the call order is reversed.Monkey
123456789101112131415161718192021222324252627282930313233343536#Import "<std>"Using std..Class StackField s:List<Double>Method New()s=New List<Double>EndMethod Push(d:Double)Self.s.Add(d)EndMethod Pop:Double()Local r:Double=0If Self.s.Count()>0 Thenr=Self.s.LastSelf.s.RemoveLast()EndReturn rEndEndFunction Main()Local myStack:=New Stack()myStack.Push(10)myStack.Push(5)Print(-myStack.Pop()+myStack.Pop())myStack.Push(10)myStack.Push(5)Local s:Double=myStack.Pop(),n:Double=myStack.Pop()Print(n-s)EndFebruary 7, 2017 at 4:16 pm #6982I don’t see the problem
this is what you are doing on the first one:
>Print(-5+10)
and the second:
>Print (10-5)
and I am getting
5
5
which is correct.February 7, 2017 at 5:37 pm #6985I am getting:
Mx2cc version 1.1.02
-5
5Finished debugging app.
which is not correct… if RVAL is evaluated from left to right :-/
I agree with you it should be :
5
5February 7, 2017 at 5:50 pm #6986That’s weird. I am getting 5 and 5 and I am using 1.1.0.3 which I dowloaded and compiled it from Github from develop section. The about monkey2 in the help says 1.1.02 but mx2cc says 1.1.03.
Thats on OSX.February 7, 2017 at 6:01 pm #6987I’m on Windows 10 and I’m using the monthly build from the patreon download link.
I’ll download the last version from github and try again.
Thanks for the replyFebruary 7, 2017 at 6:27 pm #6988Same result with Mx2xx 1.1.03…
Mx2cc version 1.1.03
-5
5
Finished debugging app.Have you tried my test ?
Monkey
123456789101112Function Main()Local myStack:=New Stack()myStack.Push(10)myStack.Push(5)Print(-myStack.Pop()+myStack.Pop())myStack.Push(10)myStack.Push(5)Local s:Double=myStack.Pop(),n:Double=myStack.Pop()Print(n-s)EndFebruary 7, 2017 at 6:52 pm #6990Are you sure the last example works as is. I get an illegal use of Generic.. when I try to run it.
I had to declare the stack as <int> for it to run.and I do get the correct results:
Attachments:
February 7, 2017 at 7:11 pm #6992February 7, 2017 at 8:00 pm #6993The line compiles to
bb_print(bbString((-f0.l_myStack->m_Pop()+f0.l_myStack->m_Pop())));
So it would appear that MinGW is calling the methods in reverse.
This can be a problem as it creates an inconsistency across platforms. I have confirmed that Android build processes left to right. Example below prints 5 on Android and -5 on Windows. (Sorry, haven’t figured out yet how to print values on Android without mojo yet)
Monkey
1234567891011121314151617181920212223242526272829303132#Import "<std>"#Import "<mojo>"Using std..Using mojo..Class Test Extends WindowField gi:intMethod OnRender( display:Canvas ) Overridegi = 0App.RequestRender()display.Clear(Color.Black)display.DrawText(-Fun1()+Fun1(),10,10)EndMethod Fun1:Int()gi = gi + 5Return giEnd MethodEndFunction Main()New AppInstanceNew TestApp.Run()EndFebruary 7, 2017 at 8:10 pm #6994Arg… This seems to be bind to the windows version. I have the same result on another windows PC.
Maybe a bug ???
?@tomtoad> Yes, you’re right. I understand this is a MingW issue. But this can’t stay as is…
I found documentation about this problem :
http://stackoverflow.com/questions/949433/why-are-these-constructs-using-undefined-behavior— / —
C99 standard are 6.5 Expressions, §2Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be read only to determine the value to be stored.
and 6.5.16 Assignment operators, §4:
The order of evaluation of the operands is unspecified. If an attempt is made to modify the result of an assignment operator or to access it after the next sequence point, the behavior is undefined.
Question :
Should Monkey2 leave us with “undefined behavior” (or manage the call order to have the same result on every OS) ?Attachments:
February 7, 2017 at 8:16 pm #6999–myStack.Pop()+myStack.Pop()
There is no ‘correct’ order for evaluation here – c++ is free to evaluate args of operators in any order (except for ‘And’, ‘Or’ and ‘?’) so mx2 does this too. Ditto with monkey, perhaps even bmx?
Also be very careful with, eg: Blah( ReadInt(),ReadInt(),ReadInt() ) etc! This is generally the ‘classic’ example of this…
February 7, 2017 at 8:36 pm #7001Thanks for your help. I will take care to write :
Monkey
12Local s:Double=myStack.Pop(),n:Double=myStack.Pop()Print(n-s)instead of :
Monkey
1Print(-myStack.Pop()+myStack.Pop())This is the first time I got this issue. The others languages I used manage the call from left to right.
I have learnt a lot today ?February 7, 2017 at 9:36 pm #7007Yeah, it’s probably odd if you’ve never encountered it before, but it allows the compiler to make more aggressive optimizations.
For example, there’s an algorithm that can optimally (ie: ‘perfectly’) allocate registers for expression trees simply by going down the ‘busiest’ branch of the tree first, allocating registers as necessary and freeing them after use (I think that’s how it worked…). Blitz3d used something like this from memory.
February 7, 2017 at 10:00 pm #7008Jihem, in C++ your solution would not help and IMHO would be prone to even more varied compilation results with Debug and Release likely to behave differently.
If it works for monkey2 (comma separated stuff ends up semicolon separated in C++) then it should be documented if it is not already.
February 8, 2017 at 11:48 am #7016Hi, Simon
I have read this : http://en.cppreference.com/w/cpp/language/eval_order
If I understood correctly (I’m not a native english speaker), I ‘m right :10) In list-initialization, every value computation and side effect of a given initializer clause is sequenced before every value computation and side effect associated with any initializer clause that follows it in the brace-enclosed comma-separated list of initalizers.
-
AuthorPosts
You must be logged in to reply to this topic.