Found a BUG in OR-Operator
Donald.Peter
Posts: 13
Hi community
(Sorry, my english is very bad)
I belive, i found a bug in the order of OR-Operator (BOR, |)
There is my test code:
And that's the result:
(0000022603) Testing BOR (|) ... (X=$40)
(0000022605) Testing var Integer: X | $20 => 96==96 -> SUCCESS
(0000022605) Testing var Long : X | $20 => 96==96 -> SUCCESS
(0000022605) Testing fix Integer: X | $20 => 96==96 -> SUCCESS
(0000022606) Testing fix Long : X | $20 => 96==96 -> SUCCESS
(0000022607) Testing literal : X | $20 => 96==96 -> SUCCESS
(0000022607) Testing var Integer: $20 | X => 32!=96 -> FAILED
(0000022608) Testing var Long : $20 | X => 32!=96 -> FAILED
(0000022609) Testing fix Integer: $20 | X => 96==96 -> SUCCESS
(0000022609) Testing fix Long : $20 | X => 96==96 -> SUCCESS
(0000022611) Testing literal : $20 | X => 96==96 -> SUCCESS
Is that a bug?
If yes, where i can report this problem, and what is the solution?
(Sorry, my english is very bad)
I belive, i found a bug in the order of OR-Operator (BOR, |)
There is my test code:
ROGRAM_NAME = 'Operator-Problem' DEFINE_CONSTANT integer nFixInt = $40 long nFixLng = $40 DEFINE_VARIABLE volatile integer nInt volatile long nLng define_function Validate(char msg[], long result, integer value) { if(result == value) send_string 0, "msg, itoa(result), '==', itoa(value), ' -> SUCCESS'" else send_string 0, "msg, itoa(result), '!=', itoa(value), ' -> FAILED'" } DEFINE_START nInt = $40 nLng = $40 send_string 0, 'Testing BOR (|) ... (X=$40)' // Variable Validate('Testing var Integer: X | $20 => ', nInt | $20, $60) Validate('Testing var Long : X | $20 => ', nLng | $20, $60) Validate('Testing fix Integer: X | $20 => ', nFixInt | $20, $60) Validate('Testing fix Long : X | $20 => ', nFixLng | $20, $60) Validate('Testing literal : X | $20 => ', $40 | $20, $60) Validate('Testing var Integer: $20 | X => ', $20 | nInt, $60) Validate('Testing var Long : $20 | X => ', $20 | nLng, $60) Validate('Testing fix Integer: $20 | X => ', $20 | nFixInt, $60) Validate('Testing fix Long : $20 | X => ', $20 | nFixLng, $60) Validate('Testing literal : $20 | X => ', $20 | $40, $60)
And that's the result:
(0000022603) Testing BOR (|) ... (X=$40)
(0000022605) Testing var Integer: X | $20 => 96==96 -> SUCCESS
(0000022605) Testing var Long : X | $20 => 96==96 -> SUCCESS
(0000022605) Testing fix Integer: X | $20 => 96==96 -> SUCCESS
(0000022606) Testing fix Long : X | $20 => 96==96 -> SUCCESS
(0000022607) Testing literal : X | $20 => 96==96 -> SUCCESS
(0000022607) Testing var Integer: $20 | X => 32!=96 -> FAILED
(0000022608) Testing var Long : $20 | X => 32!=96 -> FAILED
(0000022609) Testing fix Integer: $20 | X => 96==96 -> SUCCESS
(0000022609) Testing fix Long : $20 | X => 96==96 -> SUCCESS
(0000022611) Testing literal : $20 | X => 96==96 -> SUCCESS
Is that a bug?
If yes, where i can report this problem, and what is the solution?
0
Comments
Functions are destructive in respect to their arguments.
In other words, when you plug a variable (nInt) into the function as an argument, it will change the value of the variable (nInt).
If you "RETURN" the result instead of recycling the variable in the argument it should work as desired.
I believe using the (OR) expression in the function's argument modifies the variable to the result of the expression ($60).
You may wan to avoid using expressions with variables in function arguments just for that reason. It can cause unintended results.
this function is only a utility to show difference results on console...
If you direct assign the operation as a term to the variable,
the result 2 is wrong:
Look:
Can you see, what I mean?
Yes, I do see what you mean now.
Very strange. Especially because it only seems to error when it's a "CONSTANT OR VARIABLE" not "VARIABLE OR CONSTANT".
I guess it's time for an AMX engineer to chime in on this one.
Yeah, and I even tried it with the numbers 1 OR 2, with the same results.
It baffles my mind that a bug in such an inherent command could go unnoticed for so long.
Admittedly, if and when I use bit wise operators with variables, I always express the variable 1st and the constant second (just seems to make sense in that order), therefore I've never encountered the issue.
Interestingly, a type_cast on the constant works. Looks like the NetLinx interpreter isn't initializing variables that are evaluated after constants. I recommend reporting the bug to AMX, as they don't always respond to the forum: support@amx.com, or 800-932-6993
rememer - Type_cast has more to do with eliminating annoying warnings during comple than the actual running of the program.
agreed... as a genral rule I do not use type_cast. I just try to do it anotehr way. I don't like operating in the territory where you have to 'fool' the cmpliler into being okay with what your're doing.
Yes. But in this case it shows important information about the behavior of the bug so that it can be fixed by AMX (or understood by the community). The point is not that NetLinx programmers should be blindly using type_cast() to make the problem go away; the point is that type_cast() is not converting data widths but copying memory in this case. It behaves like it’s copying the $20 constant into the same lexical scope as the int40 local variable so they can be evaluated together.
Here’s the same example using a different method that show’s it’s a problem with the scope the expression is evaluated in:
And here’s a picture that shows what we can deduce is happening inside the “black box” (NetLinx interpreter):
Interesting deduction my dear Watson...
But it doesn't seem to explain why it functions correctly when the order of operation is reversed.
i.e.
send_string 0, "'int40 | $20: ', itoa(int40 | $20)"; // => 96 ($60) - CORRECT
There may be conditional logic in the NetLinx interpreter that makes it order dependent, or there may be an error in the lexer/parser grammar that's causing the local variable to be classified as a constant (which isn't a constant, can't be found, and is never initialized). Unfortunately, we'd have to have access to the source code to be able to answer that question for certain.
If this kind of thing interests you, I recommend the ebook How To Create Your Own Freaking Awesome Programming Language. I also have an unfinished NetLinx lexer and parser floating around if you're curious to see what those look like.