| 08-17-2008, 05:52 AM | #1 |
Well, yes, it does. However, consider the following two functions: JASS:function feature1 takes nothing returns string local string s = "aaa" local string c local integer i = 0 loop set c = SubString(s, i, i + 1) set i = i + 1 exitwhen c == null endloop if c == null then return "NULL" endif return "???" endfunction JASS:function feature2 takes nothing returns string local string s = "aaa" local string c local integer i = 0 loop set c = SubString(s, i, i + 1) set i = i + 1 exitwhen c != "a" endloop if c == null then return "NULL" endif return "???" endfunction And some basic call: call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, feature1()) call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, feature2()) Personally, I was expecting both to say "NULL". However, only the first one does... Yes, both loops run as expected, three times, ... As a work-around, changing the final test to c == "" returns the expected result. Obviously, that fails in the first function. And shouldn't be needed anyway. So, why does the c == null test fail in the second function? Because testing a string against a string instead of null changes the null to the empty string doesn't sound like an explanation. |
| 08-17-2008, 06:45 AM | #2 |
I suspect the underlying string format is actually a null-terminated string. If so, all those unexpected behavior makes sense. In a null-terminated string, a character value of 0 ('\0', or null) indicates the end of the string. Note that the null I just mentioned is a null "character", not null "string" (so don't be confused). "apple" = [a][p][p][l][e][\0] "" = [\0] So, SubString("aaa",3,4) would return [\0]. That's equivalent to an empty string, "". The null you're checking in Jass is null "string", which denotes no reference to a string. That's a completely different thing. |
| 08-17-2008, 07:49 AM | #3 |
> SubString("aaa",3,4) would return [\0]. That's equivalent to an empty string, "". Well, "" == null fails as expected. |
| 08-17-2008, 10:27 AM | #4 |
It appears that both "" and null are 2 different strings. null takes up the 0 slot on the string table, while "" takes up the 1 slot on the string table. Making a comparison will return false because they are different strings. ( 1 != 0 ) The other interesting thing is that a null string doesn't happen at the end of a string, like thougt, but another character over. for example, the string "abc" [a] [b] [c] [""] [null] using substring to get each char, that is what would come out of that string. JASS:function string2table takes string s returns integer return s return 0 endfunction function PrintStringTable takes string s returns nothing local integer i = string2table(s) call BJDebugMsg("string table for "+s+": "+I2S(i)) endfunction function isNull takes string s returns boolean return s == null or s == "" endfunction function feature1 takes nothing returns string local string s = "aaa" local string c local integer i = 0 loop set c = SubString(s, i, i + 1) set i = i + 1 if c == null then exitwhen true endif endloop if c == null then return "NULL" endif return "???" endfunction function feature2 takes nothing returns string local string s = "aaa" local string c local integer i = 0 loop set c = SubString(s, i, i + 1) set i = i + 1 if c != "a" then exitwhen true endif endloop if c == null then return "NULL" endif return "???" endfunction function feature3 takes nothing returns string local string s = "aaa" local string c local integer i = 0 loop set c = SubString(s, i, i + 1) set i = i + 1 call PrintStringTable(c) if c == null then exitwhen true endif endloop call PrintStringTable(c) call BJDebugMsg("count :"+I2S(i)) if c == null then return "NULL" endif return "???" endfunction function feature4 takes nothing returns string local string s = "aaa" local string c local integer i = 0 loop set c = SubString(s, i, i + 1) set i = i + 1 call PrintStringTable(c) if c == "" then exitwhen true endif endloop call PrintStringTable(c) call BJDebugMsg("count :"+I2S(i)) if c == "" then return "NULL" endif return "???" endfunction function feature5 takes nothing returns string local string s = "aaa" local string c local integer i = 0 loop set c = SubString(s, i, i + 1) set i = i + 1 if c == null then exitwhen true endif endloop if isNull(c) then return "NULL" endif return "???" endfunction function feature6 takes nothing returns string local string s = "aaa" local string c local integer i = 0 loop set c = SubString(s, i, i + 1) set i = i + 1 if c != "a" then exitwhen true endif endloop if isNull(c) then return "NULL" endif return "???" endfunction //=========================================================================== function InitTrig_Untitled_Trigger_001 takes nothing returns nothing //call BJDebugMsg(feature1()) // NULL //call BJDebugMsg(feature2()) // ??? call BJDebugMsg(feature3()) // NULL call BJDebugMsg(feature4()) // NULL //call BJDebugMsg(feature5()) // NULL //call BJDebugMsg(feature6()) // NULL endfunction feature1 and feature2 are the same as here, except changes to the if/then/else check to prove it has nothing to do with exitwhen. feature3 and feature4 are to demonstrate what I said above about the "" and null. The loop even goes 1 farther on the first, since it has to get past the "" and then reach null. feature5 and feature6 is feature1 and feature2 but using a check for both "" and null. As expected, they both return null since a null string is either "" or null and the isNull() function checks for both. Conclusions: JASS:null != "" substring("aaa", 3, 4) == "" substring("aaa", 4, 5) == null I guess to check for a nullstring, its best to check |
| 08-17-2008, 11:04 AM | #5 | |
Heh, see how one careless assumption can completely prevent you from figuring out what's wrong. Quote:
|
| 08-17-2008, 11:38 AM | #6 |
Well, this assumption is based on countless scripts and functions that all loop until null. One famous member here though is indeed using exitwhen ... == "" or ... == null in one of his systems, from at least one year ago... Ah well. Case closed. |
| 08-17-2008, 12:05 PM | #7 |
Btw, why you don't use the string length ? |
| 08-17-2008, 12:15 PM | #8 |
To save a function call. |
