Bug, or user error?
travis
Junior Member
PROGRAM_NAME='test'
DEFINE_DEVICE
TP = 11001:1:0
DEFINE_VARIABLE
DEFINE_CALL'TEST'{
LOCAL_VAR CHAR testCmd[20]
LOCAL_VAR INTEGER x
local_var integer temp
x = $80
testCmd = "$FD,$81,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$AB,01,x,$00,$00,$00,$00,$00,$00,$00,$AA"
F_TEST(testCmd)
testCmd = "$FD,$82,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$AB,01,x,$00,$00,$00,$00,$00,$00,$00,$AA"
F_TEST(testCmd)
testCmd = "$FD,$83,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$AB,01,x,$00,$00,$00,$00,$00,$00,$00,$AA"
F_TEST(testCmd)
}
DEFINE_FUNCTION INTEGER F_TEST(CHAR msg[]){
local_var INTEGER iAddr
local_var INTEGER cCmd
local_var CHAR cData[7]
IF(LENGTH_STRING(msg > 10)){
msg = MID_STRING(msg,11,10)
}
cCmd = msg[2]
SEND_STRING 0, "'cCmd ', ITOA(cCmd)"
}
DEFINE_EVENT
BUTTON_EVENT[TP, 1]
{
PUSH:{
CALL'TEST'
}
}
DEFINE_PROGRAM
If you set a breakpoint and single step, you get different output
Comments
-
PROGRAM_NAME='test' DEFINE_DEVICE TP = 11001:1:0 DEFINE_VARIABLE DEFINE_CALL'TEST'{ LOCAL_VAR CHAR testCmd[20] LOCAL_VAR INTEGER x local_var integer temp x = $80 testCmd = "$FD,$81,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$AB,01,x,$00,$00,$00,$00,$00,$00,$00,$AA" F_TEST(testCmd) testCmd = "$FD,$82,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$AB,01,x,$00,$00,$00,$00,$00,$00,$00,$AA" F_TEST(testCmd) testCmd = "$FD,$83,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$AB,01,x,$00,$00,$00,$00,$00,$00,$00,$AA" F_TEST(testCmd) } DEFINE_FUNCTION INTEGER F_TEST(CHAR msg[]){ local_var INTEGER iAddr local_var INTEGER cCmd local_var CHAR cData[7] IF(LENGTH_STRING(msg > 10)){ msg = MID_STRING(msg,11,10) } cCmd = msg[2] SEND_STRING 0, "'cCmd ', ITOA(cCmd)" } DEFINE_EVENT BUTTON_EVENT[TP, 1] { PUSH:{ CALL'TEST' } } DEFINE_PROGRAM
If you set a breakpoint and single step, you get different output
If you watch the msg variable in debug you can see what's happening. I have no idea why the variable is keeping its value from the first call of F_Test (like a normal local variable) when you run normally but is being reset with subsequent calls when you single step, but that's what's happening. When you run normally, the value of msg is staying the same for the subsequent calls and your if() fails.
Probably you already know what the solution is -- don't modify the value of the calling parameter inside the subroutine.
Something like:DEFINE_FUNCTION INTEGER F_TEST(CHAR msg[]){ local_var INTEGER iAddr local_var INTEGER cCmd local_var CHAR cData[7] local_var char msg2[10] IF(LENGTH_STRING(msg > 10)){ msg2 = MID_STRING(msg,11,10) } cCmd = msg2[2] SEND_STRING 0, "'cCmd ', ITOA(cCmd)" }
To answer the question -- I think it's a bug. -
It's actually a choice that has to be made when creating a compiler:
http://qntm.org/call
Some languages support both ways if you flag the parameter name in the function, NetLinx does not. -
It's actually a choice that has to be made when creating a compiler:
http://qntm.org/call
Some languages support both ways if you flag the parameter name in the function, NetLinx does not.
I understand call by reference and call by value, but saying that Netlinx is call by reference doesn't explain the behavior that we're seeing here. At least, it doesn't explain it to me.
I understand that in the subroutine F_TEST the value of the variable that is being passed as a parameter is being changed by the subroutine. But then,F_TEST terminates and the parameter is modified and then F_TEST is being called again. Call by reference implies to me that the exact same memory location is being modified with each assignment to the variable so that when F_TEST is called the second time the value in that memory location should be the value that it has in the calling code. That is how it appears to work when you step through the code using debug. Surely the code should not work differently when using debug, should it? -
Hedberg, you are correct and I'm sorry - this is a bug in debug.
I traced it down to mainly a problem with the "if" test in F_TEST():
IF(LENGTH_STRING(msg > 10))
When you change it to what he probably intended to write:
IF(LENGTH_STRING(msg) > 10)
Then debug and normal runs act the same.
Not sure why debug mode would treat LENGTH_STRING(msg>10) as string with length.
(msg>10) should always evaluate to an integer (boolean) non-array value of 0 or 1 with no length -- msg the string is either > 10 the integer or it isn't. So length_string of that single 0 or 1 should always return 0 and F_TEST() should never execute msg = MID_STRING(msg,11,10) -
IF(LENGTH_STRING(msg > 10))
AAAAAUUGHGGGffff1#$%!
Categories
- All Categories
- 2.5K AMX General Discussion
- 922 AMX Technical Discussion
- 514 AMX Hardware
- 502 AMX Control Products
- 3 AMX Video Distribution Products
- 9 AMX Networked AV (SVSI) Products
- AMX Workspace & Collaboration Products
- 3.4K AMX Software
- 151 AMX Resource Management Suite Software
- 386 AMX Design Tools
- 2.4K NetLinx Studio
- 135 Duet/Cafe Duet
- 248 NetLinx Modules & Duet Modules
- 57 AMX RPM Forum
- 228 MODPEDIA - The Public Repository of Modules for Everyone
- 943 AMX Specialty Forums
- 2.6K AMXForums Archive
- 2.6K AMXForums Archive Threads
- 1.5K AMX Hardware
- 432 AMX Applications and Solutions
- 249 Residential Forum
- 182 Tips and Tricks
- 146 AMX Website/Forums