Page 1 of 1 1
Topic Options
#202387 - 2011-06-01 04:36 AM Bug when checking equality with 0
It_took_my_meds Offline
Hey THIS is FUN
*****

Registered: 2003-05-07
Posts: 273
Loc: Sydney, Australia
Dear Ruud et. al.,

I've found a bug in 4.61 that incorrectly determines zero to be equal to a non-empty string. Please see the code below.

 Code:
Break On
If 0 = "a"
	? "This is wrong."
EndIf

If Not "a" = 0
	? "This is correct."
EndIf


The simple work around is to put 0 on the right hand side of the equality check.

Regards,

Richard

Top
#202388 - 2011-06-01 05:15 AM Re: Bug when checking equality with 0 [Re: It_took_my_meds]
Allen Administrator Online   shocked
KiX Supporter
*****

Registered: 2003-04-19
Posts: 4557
Loc: USA
I'm pretty sure there is an explanation for this. I'll let Ruud or Lonk explain it, since I know they understand that stuff better than I.

You might look at the latest golf tourney and I think this is exactly the same type of thing me and Jochen ran into.

Top
#202389 - 2011-06-01 05:43 AM Re: Bug when checking equality with 0 [Re: Allen]
It_took_my_meds Offline
Hey THIS is FUN
*****

Registered: 2003-05-07
Posts: 273
Loc: Sydney, Australia
Thanks Allen. I've had a read through the forum on the latest golf round. I found a somewhat cryptic post by Jochen about a statement evaluating to true when $ = 0. Is that what you are referring to?

In any case, it seems pretty clear to me that 0 does not equal "a" no matter how you slice it. I did mention a workaround above but I'm afraid that's only useful if you know that the statement on the left hand side is going to equal 0 before the script is run.

Top
#202390 - 2011-06-01 06:05 AM Re: Bug when checking equality with 0 [Re: Allen]
It_took_my_meds Offline
Hey THIS is FUN
*****

Registered: 2003-05-07
Posts: 273
Loc: Sydney, Australia
OK, I had another read through and found the link you posted where this was discussed. http://www.kixtart.org/forums/ubbthreads.php?ubb=showflat&Main=26945&Number=199573#Post199573

I still assert that this is a bug however.

Top
#202391 - 2011-06-01 04:11 PM Re: Bug when checking equality with 0 [Re: It_took_my_meds]
Richard H. Administrator Offline
Administrator
*****

Registered: 2000-01-24
Posts: 4946
Loc: Leatherhead, Surrey, UK
It's not a bug, it is expected behaviour.

Expressions are coerced to the same type as the value on the LHS of the comparison operator. You are coercing a string type to a numeric type, and the *numeric* value of the string "a" is zero so the expression is true.

It is no more incorrect than the following which is also true.
 Code:
If 123 = "12" + "3 Green Bottles"
	"They match!"+@CRLF
EndIf


The correct coding for what you are expecting would be:
 Code:
If CStr(0) = "a"
	"Can't possibly be true"+@CRLF
EndIf


Edited by Richard H. (2011-06-01 04:13 PM)

Top
#202395 - 2011-06-02 01:13 PM Re: Bug when checking equality with 0 [Re: Richard H.]
Glenn Barnas Administrator Offline
KiX Supporter
*****

Registered: 2003-01-28
Posts: 4400
Loc: New Jersey
Dot - er - Spot On, Richard!

Glenn
_________________________
Actually I am a Rocket Scientist! \:D

Top
#202400 - 2011-06-03 08:02 AM Re: Bug when checking equality with 0 [Re: Glenn Barnas]
It_took_my_meds Offline
Hey THIS is FUN
*****

Registered: 2003-05-07
Posts: 273
Loc: Sydney, Australia
OK well I see the logic, I'm not sure I agree with it though. This has the potential to create some unusual behaviour if you are not aware of it (I suspect many aren't).

I discovered this in a function I wrote that processes and compares information from a database. As databases can feed in different types of data I didn't know before hand what type of data was going to be on either side of the evaluation. You can imagine my surprise to discover that it was reporting that data that equalled zero also equalled data that was a string.

I guess the lesson here is that if you don't know the data type before hand you can't test for equality without also checking vartypes or casting to string first.

It still doesn't seem right to me, but at this stage I can't suggest an alternative for the KiXtart interpreter except for explicitly checking for this case (which probably wouldn't be too elegant).

Top
#202401 - 2011-06-03 08:47 AM Re: Bug when checking equality with 0 [Re: It_took_my_meds]
Arend_ Moderator Offline
MM club member
*****

Registered: 2005-01-17
Posts: 1896
Loc: Hilversum, The Netherlands
Well KiXtart allows for too much in my opinion when it comes to VarType comparisons. This would all be much more logical if you could declare the variable type when you declare the variable in the first place, much like VB.
For instance if you would have to do it like this:
 Code:
Dim $tmp As String = "a"
Dim $int As Integer = 0

You would not even think about comparing them.

Top
#202402 - 2011-06-03 09:35 AM Re: Bug when checking equality with 0 [Re: Arend_]
It_took_my_meds Offline
Hey THIS is FUN
*****

Registered: 2003-05-07
Posts: 273
Loc: Sydney, Australia
Actually I love the conversions in general, they're one of my favourite things about KiXtart; especially to boolean as it makes the language so much more naturally readable and simpler to write.
 Code:
If InStr($s, "hello") "found" EndIf

 Code:
$i = 0
$Subkey = EnumKey($key, 0)
While $SubKey
	? $SubKey
	$i = $i + 1
	$Subkey = EnumKey($key, $i)
Loop

I also think that CInt("a") should equal 0. It is only the specific case of checking for equality as mentioned above that seems odd to me.

Top
#202403 - 2011-06-03 09:51 AM Re: Bug when checking equality with 0 [Re: It_took_my_meds]
Richard H. Administrator Offline
Administrator
*****

Registered: 2000-01-24
Posts: 4946
Loc: Leatherhead, Surrey, UK
 Quote:
It still doesn't seem right to me


If everything worked the way the you assumed then you would find life very boring \:\)

 Quote:
...I can't suggest an alternative for the KiXtart interpreter except for explicitly checking for this case


There is no need to change the interpreter - you already have the ability to determine how expressions of different types are handled, including in this specific case. Like programming in any language you just need to know the rules and if you don't like the implicit handling you code explicit handling to deal with it.

KiXtart is a loosely-typed language and it's handling of different typed data reflects this. As you get exposed to other scripting / coding languages you will find that it is far from unique.

If you think beyond your initial post you will see that it has wider implications. Take this expression:
 Code:
$a = "12" + 3
$b = 12 + "3"

What should the value of the variables be? 15 or "123"?

What should happen here:
 Quote:
$a=""
$b=123
$a=Left($b,1)

Should $a=3 (numeric) or "3" (string) or "" (because $b is not a string) or should the script abort with an error because of mismatched data types?

Even "strongly" typed languages such as C will change mixed data types in expressions and leave you scratching your head in confusion at the result if you do not fully understand the rules.

This is a long way of saying that all coding languages have their idiosyncracies and each time you learn a new coding language you need to also learn its idiosyncracies if you want to code accurately and efficiently.

KiXtart's USP is the easy and elegant coding that features such as the automatic variable type coersion / casting allow.

Top
#202404 - 2011-06-03 10:06 AM Re: Bug when checking equality with 0 [Re: It_took_my_meds]
Richard H. Administrator Offline
Administrator
*****

Registered: 2000-01-24
Posts: 4946
Loc: Leatherhead, Surrey, UK
 Quote:
Actually I love the conversions in general, they're one of my favourite things about KiXtart; especially to boolean as it makes the language so much more naturally readable and simpler to write.

Code:
If InStr($s, "hello") "found" EndIf


As I seem to be pedant for the day let me point out that its not quite as simple as converting to boolean.

You already know that a know that data can be automatically cast to a type that matches the expression.

However the "truth" value of the data is not the same thing and will bite you if you are not careful.

Guess what the results of this code will be and then try it, there is at least one result that may surprise you, possible two:
 Code:
$a=0
$b=1
$c="0"
$d="1"
$e=""
$f="foo"
"a is "+IIF($a,"true","false")+@CRLF
"b is "+IIF($b,"true","false")+@CRLF
"c is "+IIF($c,"true","false")+@CRLF
"d is "+IIF($d,"true","false")+@CRLF
"e is "+IIF($e,"true","false")+@CRLF
"f is "+IIF($f,"true","false")+@CRLF

Top
#202405 - 2011-06-03 10:24 AM Re: Bug when checking equality with 0 [Re: Richard H.]
It_took_my_meds Offline
Hey THIS is FUN
*****

Registered: 2003-05-07
Posts: 273
Loc: Sydney, Australia
Yes yes I agree all that you said and am very accustomed to KiXtart's automatic casting. \:\) To answer your questions, $a = "123", $b = 15 and $b= "1" (And yes I have experience with many other languages). Automatic casting is not an issue, it's how equalities are checked that seems odd. 0 should equal "0" but IMHO, when a number is being compared to a string both should be converted to the data type that retains the most information (i.e. String). Yes, we can code around it and I wouldn't wish Ruud to change anything if it made KiXtart less efficient or broke older scripts (which it may well do).

At the least this discussion may have highlighted an idiosyncrasy of KiXtart that people should be aware of. Ruud may wish to consider the data type of both sides of the equality when evaluating if he thinks it is a good idea.

Top
#202406 - 2011-06-03 10:30 AM Re: Bug when checking equality with 0 [Re: Richard H.]
It_took_my_meds Offline
Hey THIS is FUN
*****

Registered: 2003-05-07
Posts: 273
Loc: Sydney, Australia
All the results were as I expected?
Top
#202407 - 2011-06-03 01:38 PM Re: Bug when checking equality with 0 [Re: It_took_my_meds]
Richard H. Administrator Offline
Administrator
*****

Registered: 2000-01-24
Posts: 4946
Loc: Leatherhead, Surrey, UK
Well consider what we already know:
  • 0 is false
  • Non-zero is true
  • 0 = "0" so "0" should be false
  • 0 = "foo" so "foo" should be false

So, how come the $c and $f tests are true when $c="0" and $f="foo" if we are converting to boolean?

The answer is that we are not converting to boolean. We are checking the truth of the data, which is not necessarily the same thing as the truth of the boolean value of the data.

The most common time this catches people out is when checking boolean / numeric flags in INI files using ReadProfileString() or values in the registry using ReadValue(). Both these functions return STRING data regardless of how the value is encoded, so "0" and "1" are both true which is probably not what is expected.

This means that code like the following will not work as expected if the BootPending flag is 0:
 Code:
If ReadValue("HKLM\SomePath","BootPending")
   "Cannot install, there is a restart pending"+@CRLF
EndIf


Instead, you must cast the datum to a type that will work:
 Code:
If CInt(ReadValue("HKLM\SomePath","BootPending"))
   "Cannot install, there is a restart pending"+@CRLF
EndIf

Top
#202408 - 2011-06-03 02:44 PM Re: Bug when checking equality with 0 [Re: Richard H.]
It_took_my_meds Offline
Hey THIS is FUN
*****

Registered: 2003-05-07
Posts: 273
Loc: Sydney, Australia
My understanding is that non-empty strings and non-zero numbers get cast to true in a boolean context. Likewise empty strings and 0 get cast to false.

So I find it completely logical that "0" is cast to true and 0 is cast to false in the boolean context. It is possible that this doesn't explicitly happen in Ruud's code, but the effect is the same. Ruud may wish to comment on this.

I hope we can all agree that context is what determines the way a variable is cast.

Here's another interesting result of casting the RHS to the vartype of the LHS when checking for equality.
 Code:
If 1 = 1.1
	"This is another example"
EndIf

This one is even more insidious as they are both numbers. I know, I know the LHS is an integer and the RHS is a double. However going back to my assertion before that both that sides of the equality should be converted to the data type that retains the most information, I suggest that in this equality context they should both be cast to double and then checked.

If my suggestion was followed then 0 wouldn't equal "a" and 1 wouldn't equal 1.1, but 1.1 would equal "1.1" as before, which seems to me to be logical.

Top
Page 1 of 1 1


Moderator:  ShaneEP, Arend_, Jochen, Radimus, Glenn Barnas, Allen, Ruud van Velsen, Mart 
Hop to:
Shout Box

Who's Online
1 registered (Allen) and 633 anonymous users online.
Newest Members
min_seow, Audio, Hoschi, Comet, rrosell
17881 Registered Users

Generated in 0.069 seconds in which 0.026 seconds were spent on a total of 13 queries. Zlib compression enabled.