Why does it do this?

Blitz3D Forums/Blitz3D Beginners Area/Why does it do this?

DH(Posted 2005) [#1]
Global A = 5

PP(B(),B(),B(),B(),B())
WaitKey()
End

Function PP(C,D,E,F,G)
	Print C
	Print D
	Print E
	Print F
	Print G
End Function


Function B()
	a=a-1
	Return a
End Function


output:
0
1
2
4
3


I was under the assumption that functions evaluate their argument from right to left... For the most part that is the case with the exception of the last two...


GitTech(Posted 2005) [#2]
Not every programming language evaluates from right to left (like C and C++ does). Apparently, BlitzBasic evaluates from left to right (like Pascal does).


EDIT: Oops, now I notice the strange output...

0
1
2
4
3



Rhyolite(Posted 2005) [#3]
Weird!!

Just FYI, I stepped through the code in debug mode, and 'A' is correctly decremented each call to B() and their is no error in the print order. It does look like Blitz evaluates the arguments in a strange order!!!

Blitz3D 1.90

Weird!!

Rhy :)


Floyd(Posted 2005) [#4]
This is a recurring discovery.

In general you shouldn't rely on function arguments being evaluated in any particular order. The C and C++ standards explicitly state that this order is undefined. The compiler can use any order it likes.

I don't think the Blitz documentation says anything about this. So you should just assume that you can't count on any particular order.


Rook Zimbabwe(Posted 2005) [#5]
Why... Gremlins... {shakes head} newbies!!! Why can't they see the Gremlins... {sigh}


GitTech(Posted 2005) [#6]
Oooohhhhhh.... I can see the Gremlins.... HELPPPP!!! ;)


Hujiklo(Posted 2005) [#7]
Now that is worrying me...I'm confused. Those print commands are in order, so surely it should print them in the order you set???

What happens if the C, D, E, F, G variables are global and
the print commands are not inside the function?


markcw(Posted 2005) [#8]
note that it is always the last two in
the function that are reversed.


DH(Posted 2005) [#9]
note that it is always the last two in
the function that are reversed.


True, and with Blitzmax (from my testing), you can count on the order of the arguments being evaulated in a certain order.

It would be nice to be able to count on something in a language.....


Floyd(Posted 2005) [#10]
In my opinion the right approach would be for the docs to clearly state that the order is not specified. Then the compiler may change the order and still be playing by the rules. This might be needed for optimization, which is why the C standard left the order unspecified. This applies to the operands needed by an operator as well as to arguments needed by a function.

The usual trick is to do the more complicated evaluation first. For example, suppose that b() needs more registers than a() and we want to evaluate the expression

a() + b()

as efficiently as possible. Perhaps this can be done entirely in registers only by evaluating b() before a().
Thus a() + b() needs a different left-to-right order than b() + a().


WendellM(Posted 2005) [#11]
It's a bit more work, but could right-to-left evaluation order not be made explicit:
Global A = 5

T1=B()
T2=B()
T3=B()
T4=B()
T5=B()

PP(T5,T4,T3,T2,T1)
WaitKey()
End

Function PP(C,D,E,F,G)
	Print C
	Print D
	Print E
	Print F
	Print G
End Function


Function B()
	a=a-1
	Return a
End Function
It could then be switched to left-to-right with "PP(T1,T2,T3,T4,T5)" or to whatever order is desired without worrying about the compiler's order.