Compilation with a BUG...
BlitzMax Forums/BlitzMax Programming/Compilation with a BUG...
| ||
after 2 weeks i found a very nasty BUG on a my app: this is an example: if instr("TEST","ST">0) print "NEVER" if instr("TEST","ST")>0 print "ALWAYS" the strange thing is that Blitzmax compile the wrong line without any issue... probably use of < > on string is allowed (for doing what?) and no error on the first line... |
| ||
it is allowed! first, you can compare strings with numbers. BlitzMax will compare the ASCII value: If "A">64 Print "YES" Else Print "NO" EndIf The expression "ST">0 has the result 1 Print "ST">0 second, INSTR can search for numbers inside strings. In this case the number will be converted to a string of this number: If Instr("a9bc",9) Print "YES" Else Print "NO" EndIf third, what you did is only a combination of both. your code... if instr("TEST","ST">0) print "NEVER" ...is the same like... if instr("TEST",("ST">0))=TRUE THEN print "NEVER" ...is the same like... if instr("TEST",1)=TRUE THEN print "NEVER" ...is the same like... if FALSE=TRUE THEN print "NEVER" ...is the same like... if (FALSE=TRUE) THEN print "NEVER" |
| ||
instr("TEST","ST">0) is syntantically valid although it is not what you intended. Instr( a, b ) expects two string arguments. If a,b are not strings then they must be converted to strings. The next issue is can "ST">0 be a string? The result of the comparison operator > is always True or False, which really just means 1 or 0. In order to be used by Instr the integer 1 or 0 will be converted to string "1" or "0". Now we come to the real mystery, what is the comparison operator > doing when the operands are string "ST" and integer 0? I've never seen this defined in the BlitzMax docs. But Blitz3D came with a Language Reference and the Expressions section actually spelled this out in detail. I think BlitzMax is doing the same thing. Here is the relevant portion of the Blitz3D docs: If the operands of a binary arithmetic or comparison operator are not of the same type, one of the operands is converted using the following rules: - If one operand is a custom type object, the other must be an object of the same type, or 'Null'. Else if one operand is a string, the other is converted to a string. Else if one operand is floating point, the other is converted to floating point. Else both operands must be integers. Following those rules the expression "ST">0 will become "ST">"0". This evaluates to 1 ( i.e. True ) because the character S comes after character 0 in the ASCII table. All of this is done before Instr("TEST","ST">0) can be evaluated and the result is ultimately Instr( "ST", "1" ), which is 0 because "1" is not a substring of "ST". The automatic conversion between string,float,int etc. is very convenient but occasionally produces unexpected results like Instr("TEST","ST">0) being valid code. |
| ||
very thank you for the explanation :) |