I documented it in “Spot the error” in xDev 13.5, page 13 (Sep/Oct 2015):
I was going over my code, cleaning it up and preparing it for Xojo 64-bit, paying particularly close attention to integers and potential overflow errors. I had thought I was done with overflow errors, but they find new ways to annoy me. Have a look at the following code and guess which ones evaluate to true and which ones result in false (and no peeking at the solution!):
Dim n1 As Integer = 3123456789
MsgBox Str(n1 >= 0)
Dim n2 As UInt32 = 3123456789
MsgBox Str(n2 >= 0)
Dim n3 As UInt64 = 3123456789
MsgBox Str(n3 >= 0)
Dim n4 As Int64 = 3123456789 + 8
MsgBox Str(n4 >= 0)
Dim n5 As Int64 = 2147483640 + 8
MsgBox Str(n5 >= 0)
Dim n6 As Int64 = 3000 * 1000 * 1000 * 1.2
MsgBox Str(n6 >= 0)
Dim n7 As Int64 = 3000 * 1000 * 1.2 * 1000
MsgBox Str(n7 >= 0)
Dim n8 As Variant = 3123456789
MsgBox Str(n8 >= 0)
I’ll give you the first two solutions:
n1>= 0 is false. n1 contains wrong value.
The first one is easy. After all, we are talking about overflow errors here, so I wasn’t expecting to catch you out with a simple Integer overflow. If you did get it wrong, then read what I wrote about overflow errors in the last issue (hint: Integer is the same as Int32 and can only hold values between -2,147,483,648 to 2,147,483,647).
n2>= 0 is false. n2 contains correct value.
Now this one is surprising at first sight as 3123456789 is well within the defined UInt32 range of 0 to 4294967295 (and my thanks to Norman for the explanation). But what the compiler does whenever it gets any binary operator (+, -, =, <, etc) is to first compute a common type between the operands. And for backwards compatibility reasons, the common type between signed and unsigned is signed. So for the comparison, the compiler will assume the number is a signed integer, and trying to squeeze 3123456789 into a signed integer results in an integer overflow. To deal with this you would need to specify a type by casting like this:
MsgBox Str(n2 >= UInt32(0))
This now treats both n2 and 0 as an UInt32 and therefore evaluates to true… as it should.
Now this might not be a bona fide integer overflow error, so maybe I should call it a conversion or comparison overflow error instead.
Care to try the rest?