Page 1 of 2

Why the type LONG work differently in x86 and x84 complier?

Posted: Wed Nov 10, 2021 2:15 am
by Allen
Hi,
I am new to the forum.

Long is 4 byte and suppose work the same in both x86 and x64 complier. Why is below code work differently (5.73 LTS)?

l.l=-123
If l=$FFFFFF85
Debug "work in x86 complier only"
EndIf

Thanks.

Allen

Re: Why the type LONG work differently in x86 and x84 complier?

Posted: Wed Nov 10, 2021 2:36 am
by TassyJim

Code: Select all

l.l=-123
k.l = $FFFFFF85
If l=k
Debug "works in all compilers"
EndIf
I 'think' this is what is happening:
The IF statement is converting both sides to Integer before the comparison.
Integer is the most logical for your $FFFFFF85 value.

If you force both sides to your desired type first, the comparison works for all compilers

Edit: It could also be because the default number type is Integer.

Jim

Re: Why the type LONG work differently in x86 and x84 complier?

Posted: Wed Nov 10, 2021 4:29 am
by Allen
Hi Jim,

Thanks for the quick response.

I noticed debug l (and debug K) return 8 byte hex value in x64 and 4 byte value in x86. That is why your code works as both l and k return 8 byte value. If you replace k with #K= $FFFFFF85, it won't work.

In x64, type long with negative value and show in hex value will return 8 bytes.

Thanks.

Allen Wong

Re: Why the type LONG work differently in x86 and x84 complier?

Posted: Wed Nov 10, 2021 5:49 am
by TassyJim
Don't rely on Debug to show results in your chosen type.

Your constant #K will be treated as an integer. (I think I read that here somewhere).

If you need to use constants and longs, assign the constant to a temporary long first.
Of convert the other side to integer.

As soon as I started to code for 64 bit, I learnt the hard way that Integers are your friend.
Longs will bite you.

Jim

Re: Why the type LONG work differently in x86 and x84 complier?

Posted: Wed Nov 10, 2021 6:02 am
by Allen
Hi Jim,

Thank you for the advice. Will use integer and avoid long whenever possible.

Thanks

Allen Wong

Re: Why the type LONG work differently in x86 and x84 complier?

Posted: Wed Nov 10, 2021 6:56 am
by BarryG
Just to double-check: I only code with 32-bit PureBasic for now, so is there anything wrong with me changing all my ".l" variables to ".i" with the 32-bit version (for when the time comes to switch to 64-bit)? Or is there no point with the 32-bit version?

(And before anyone asks: a lot of my users still run 32-bit Windows, so it's not an option for me to compile only as 64-bit right now).

Re: Why the type LONG work differently in x86 and x84 complier?

Posted: Wed Nov 10, 2021 7:11 am
by TassyJim
It would be best to wait for someone who knows what he is talking about, but my experience so far:

I have a reasonably sized project of 14000 lines which I used longs for just about everything.
(I should have read the manual)

When I decided to go with 64bit, keeping 32bit for users who are still on XP, I basically did a global replace for all .l to .i or (blank)
Before I did that there were unexplained crashes due to 64 bit systems using handles that didn't fit in longs.

I haven't had any problems since changing to integers but you do have to be careful if you are using external or system dlls. In those cases, you have to stick to whatever they require.

I haven't had to concern myself with aligning data bytes (yet).

Jim

Re: Why the type LONG work differently in x86 and x84 complier?

Posted: Wed Nov 10, 2021 7:37 am
by BarryG
TassyJim wrote: Wed Nov 10, 2021 7:11 amWhen I decided to go with 64bit, keeping 32bit for users who are still on XP, I basically did a global replace for all .l to .i or (blank)
Before I did that there were unexplained crashes due to 64 bit systems using handles that didn't fit in longs.
Interesting... sometimes my app crashes with an illegal memory error and I have no idea why. Not often, maybe like once per month. Everything allocated has enough buffer and is freed afterwards, and even with the Purifier on and all that stuff (showing me which source line the crash occurred), I've never been able to pinpoint exactly what was causing it. Like you, my app is compiled as 32-bit and running on a 64-bit PC. Maybe it's time to do that search and replace of ".l" to ".i" after all. I'll give it a spin for a few days and see how it goes. Thanks for potentially fixing my bug!

Re: Why the type LONG work differently in x86 and x84 complier?

Posted: Wed Nov 10, 2021 8:20 am
by TassyJim
Like you, my app is compiled as 32-bit and running on a 64-bit PC.
No problems until I re-compiled the old code for 64bit. That is when the problems appeared.

You shouldn't have any problems running 32bit programs under 64bit Windows.

Jim

Re: Why the type LONG work differently in x86 and x84 complier?

Posted: Wed Nov 10, 2021 9:22 am
by Joris
Not yet checked, but I think :

A problem can appear with saving 'user'-data, in which integers exist that can be used on both type of computers X86 and X64.
That saved 'user'-data will differ from size then, and so probably not compatible...

Re: Why the type LONG work differently in x86 and x84 complier?

Posted: Wed Nov 10, 2021 10:09 am
by BarryG
TassyJim wrote: Wed Nov 10, 2021 8:20 amNo problems until I re-compiled the old code for 64bit. That is when the problems appeared.
Oh, okay. I misunderstood. But when I checked, my own code had no ".l" in it anyway, but only modules that I got from this forum did. I won't change anything until I eventually move to 64-bit.

Re: Why the type LONG work differently in x86 and x84 complier?

Posted: Wed Nov 10, 2021 10:48 am
by AZJIO
I'm not sure exactly, but the number may be exceeded

Code: Select all

Debug Hex(2147483647) ; = $7FFFFFFF
$FFFFFF85 > $7FFFFFFF
$7FFFFFFF < $FFFFFF85

Code: Select all

Debug Val("$FFFFFF85") ; = 4294967173
PureBasic.chm
Long .l 4 bytes -2147483648 to +2147483647

Re: Why the type LONG work differently in x86 and x84 complier?

Posted: Wed Nov 10, 2021 12:35 pm
by juergenkulow

Code: Select all

; //If l=$ffffff85
; C backend x86: 
;   If (!(v_l==-123)) { goto no2; }
; C backend x64:
;   If (!(v_l==4294967173)) { goto no2; }  
; ASM backend x86:    
;   MOV    ebx,dword [v_l]
;   CMP    ebx,-123
;   JNE   _EndIf2
; ASM backend x64 
;   MOVSXD r15,dword [v_l]
;   MOV    rax,4294967173
;   CMP    r15,rax
;   JNE   _EndIf2  

Re: Why the type LONG work differently in x86 and x84 complier?

Posted: Wed Nov 10, 2021 1:17 pm
by Allen
In 32bit signed integer -123 is $FFFF FF85, in 64 bit signed integer -123 is $FFFF FFFF FFFF FF85. It seems to me in x64 complier, long (suppose same as 32 bit signed integer) return as a 64 bit signed integer for the value of -123.

If I change the if line to "if l &$FFFFFFFF =$FFFFFF85", it worked for x86 and x64.

Allen Wong

Re: Why the type LONG work differently in x86 and x84 complier?

Posted: Wed Nov 10, 2021 2:04 pm
by Allen
For below code in x64, type integer return correct value (in hex) while long does not. It is strange.

l.l=$FFFFFF85
i.i=$FFFFFF85
Debug l
Debug i

I think I shall listen to Jim and avoid to use long, only that I lose the option to use 32 bit integer in x64.

Anyway thanks for all the input.

Allen Wong