Wrong evaluation of expression

Recently I added a break statement tot my small app, that would signal
a condition for “reading beyond the disk end” in the debugger:

IF LongFilePointer > (1024 * 1024 * 1024 * 1024) THEN
BREAK
END IF

However, this condition already occurs when the value of LongFilePointer
(an UINT64) is much smaller then the right hand side in the comparison.

Replacing the expression with the equivalent constant 1099511627776 solves
the issue.

It looks like the expression is truncated (MOD 32bit ?) by the preprocessor or
compiler.

Possibly a bug ?

Windows 10, 64 bit, 64 bit app.

32bit truncation would result in a value of ZERO
1099511627776 is a 44bit number 0x10000000000

what do you see when you do this?

		MsgBox Str(1024*1024*1024*1024)
		Dim x As UInt64=1024*1024*1024*1024
		MsgBox Str(x)
		Dim y As UInt64=1024
		MsgBox Str(y*y*y*y)

on macOS 32bit I get 0 and 0 and 1099511627776
on macOS 64bit I get 1099511627776 and 1099511627776 and 1099511627776

Dave, in all these cases the value of 1099511627776 is shown by MsgBox.

Strange …

If you have a small app that show this you can file a Feedback case. This way Xojo team can see if there is a bug.

You should include Xojo version, windows version and other details.

Alberto,

I will do that. It might be that the compiler is confused, as the debugger for Windows only
runs in 32-bit mode. But 64 bit values should be allowed in any case in expressions.

(Xojo, R17.3, Windows 10).

I have a Windows 7 machine if you want me to test your sample there.

If you have xDev then read my article about integer overflow errors.

You have 1024, an integer. A 32bit Integer! You multiply with 1024, another 32bit integer. The result is an integer of 1,048,576, another 32bit Integer.

You multiply that integer with another integer of 1024. BANG! Integer overflow error in your app.

If you use 1099511627776, then that is stored as a 64bit Integer.

[quote=364696:@Markus Winter]If you have xDev then read my article about integer overflow errors.
You have 1024, an integer. You multiply with 1024, another integer. The result is an integer of 1,048,576
You multiply that integer with another integer of 1024. BANG! Integer overflow error.[/quote]
However… he said it was a 64bit app… therefore it should be 64 multiplication
and under 64bit macOS it is… and based on what he said, (running my example) he gets the “correct” result

it seems that the COMPARE may be the issue… not the multiplication itself

You are right, it is not overflow. On my Mac running as 32bit:

[code]dim LongFilePointer as UInt64 = 102410241024*1024 // 32bit: 0

dim x1 as integer = 1024 // 32bit: 1024
dim x2 as integer = 10241024 // 32bit: 1048576
dim x3 as integer = 1024
10241024 // 32bit: 1073741824
dim x4 as integer = 1024
102410241024 // 32bit: 0

Dim n1 As Integer = 3123456789 // 32bit: -1171510507 <- overflow

Dim n2 As UInt32 = 3123456789 // 32bit: 3123456789

Dim n3 As UInt64 = 3123456789 // 32bit: 3123456789

Dim n4 As Int64 = 3123456789 + 8 // 32bit: 3123456797

Dim n5 As Int64 = 2147483640 + 8 // 32bit: -2147483648 <- overflow

Dim n6 As Int64 = 3000 * 1000 * 1000 * 1.2 // 32bit: -1553960755 <- overflow

Dim n7 As Int64 = 3000 * 1000 * 1.2 * 1000 // 32bit: 3600000000

Dim n8 As Variant = 3123456789 // 32bit: 3123456789

[/code]

Why are LongFilePointer and x4 zero on 32bit app Mac? It should overflow, not result in zero.

I tried it in REALstudio 2012R1.2 and Xojo 2013 R3.3 with the same result.

Markus… per my post above… IT DOES OVERFLOW on macOS 32bit, at least with Sierra and Xojo2016r4

what would you expect… it results in a 44bit answer… if you take the lower 32bits… they are all zero
however 102310231023*1023 is also a 44bit answer
1095222947841 or 0xFF005FF001
but results in 6287361 or 0x5FF001 (which is also the lower 32bits)

Someone file a bug report!

I’m failing to see the bug… at least as far as 32bit vs 64bit multiplication is concerned

Shouldn’t there be some kind of OverflowException?

Thanks Dave, got it now.

Tim, not a bug, just the way computers work.

depending on the underlying functions… it might not be possible… such is the nature of the INTEGER datatype

Missing handling integer overflow- and underflow-exceptions are bugs, but Xojo is not the only programming language that has that bug.
Processors have a carry and a overflow flag built in that can be used to handle these situations.
There are enough examples where missing this kind of errorhandling has caused severe disasters, read the examples in this wiki: https://en.wikipedia.org/wiki/Integer_overflow
Many years ago i mentioned it already to Xojo (then named Real software) but still nothing changed.

This affects all types of integer including the currency type, that has even more flaws (division by zero).

I was curious… so I tried this in 64bit Swift to see if it handled it differently or the same as Xojo

[b]// THIS IS SWIFT CODE... NOT XOJO CODE[/b]
 var x : UInt64 = 1024
 for i in(1...10) {
           print("\\(i) : \\(x)")
            x=x*1024
}

results :
1 : 1024
2 : 1048576
3 : 1073741824
4 : 1099511627776
5 : 1125899906842624
6 : 1152921504606846976
BOOM… EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0

so SWIFT raises an exception on overflow

Now I would be curious to see what “Xojo for iOS” did

Thanks all for your insight.

I tested Dave’s MsgBox -approach, and it shows no problems with the original expression in
the comparison in the 64-bit (Windows 10) case, with 64-bit code.

But when running as a 32-bit app, necessary for using the debugger in the Windows case,
the problem arises.

As one is allowed to use 64 bit integers in 32 bit code also, this problem should not arise.

If the assembly-code generated could be viewed (like in Delphi or the former OS/2 VisualAge e.g.),
it would be clear that the code generated for the expression is not automatically adapted for
the correct 64-bit comparison, as obligatory by the uint64 variable in the left side.

@ALBERTO SANTOS

It is quite likely that on a 32 bit system with 32-bit code the same error would be seen,
as the LongFilePointer would be uint64 still.

Xojo does not use the left hand side of the expression at all in determining the appropriate variable type to use in the right hand side.

I use ctype() everywhere 64-bit values are involved.

IF LongFilePointer > ctype(1024 * 1024 * 1024 * 1024, uint64) THEN ...