Compilation with a BUG...

BlitzMax Forums/BlitzMax Programming/Compilation with a BUG...

Fielder(Posted February) [#1]
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...


Midimaster(Posted February) [#2]
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"



Floyd(Posted February) [#3]
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.


Fielder(Posted February) [#4]
very thank you for the explanation :)