#202387 - 2011-06-01 04:36 AM
Bug when checking equality with 0
|
It_took_my_meds
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.
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
|
|
|
|
#202391 - 2011-06-01 04:11 PM
Re: Bug when checking equality with 0
[Re: It_took_my_meds]
|
Richard H.
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.
If 123 = "12" + "3 Green Bottles"
"They match!"+@CRLF
EndIf
The correct coding for what you are expecting would be:
If CStr(0) = "a"
"Can't possibly be true"+@CRLF
EndIf
Edited by Richard H. (2011-06-01 04:13 PM)
|
Top
|
|
|
|
#202401 - 2011-06-03 08:47 AM
Re: Bug when checking equality with 0
[Re: It_took_my_meds]
|
Arend_
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:
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
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.
If InStr($s, "hello") "found" EndIf
$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
|
|
|
|
#202404 - 2011-06-03 10:06 AM
Re: Bug when checking equality with 0
[Re: It_took_my_meds]
|
Richard H.
Administrator
   
Registered: 2000-01-24
Posts: 4946
Loc: Leatherhead, Surrey, UK
|
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:
$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
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
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
   
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:
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:
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
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.
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
|
|
|
|
Moderator: ShaneEP, Arend_, Jochen, Radimus, Glenn Barnas, Allen, Ruud van Velsen, Mart
|
0 registered
and 561 anonymous users online.
|
|
|