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

Just starting out? Need help? Post your questions and find answers here.
Saboteur
Enthusiast
Enthusiast
Posts: 272
Joined: Fri Apr 25, 2003 7:09 pm
Location: (Madrid) Spain
Contact:

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

Post by Saboteur »

Long type is always 4 bytes. But Integer type can be 4 bytes (x86) or 8 bytes (x64). That's the problem.

In x64 the code must be:

Code: Select all

l.l=$FFFFFF85
i.i=$FFFFFFFFFFFFFF85
Debug l
Debug i
[:: PB Registered ::]

Win10 Intel core i5-3330 8GB RAM Nvidia GTX 1050Ti
Allen
Enthusiast
Enthusiast
Posts: 103
Joined: Wed Nov 10, 2021 2:05 am

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

Post by Allen »

@Saboteur

I get your point, since the hex value of different type is different, to assign the same value to differnt type I need to use the correct hex value.

i.i=-123
l.l=-123
w.w=-123
b.b=-123

if use hex value should be
i.i=$FFFFFFFFFFFFFF85
l.l=$FFFFFF85
w.w=$FF85
b.b=$85

Thanks

Allen Wong
User avatar
DeanH
Enthusiast
Enthusiast
Posts: 274
Joined: Wed May 07, 2008 4:57 am
Location: Adelaide, South Australia
Contact:

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

Post by DeanH »

BarryG wrote: Wed Nov 10, 2021 6:56 am 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).
Months ago I ran into the problem with PB6-x64 in which the values returned by #PB_Any were vastly different to the 32-bit compiler. In my source code I changed most of the .l to .i and it mostly worked. The only problems I ran into involved special structures or includes developed by others. The problem I had with the PDF code was one example but I have managed to work around that and there were few structure issues.

I have estimated about 15% of my users, mostly schools, still have 32-bit systems but that is reducing fairly rapidly. Most are Win 7 but there are a few 8, 10 and, surprisingly, even XP. So I have been maintaining both 32-bit and 64-bit versions. I have written the source code so it compiles unchanged with both 32-bit and 64-bit PB compilers. The only problem I have run into is with 32-bit DLLs for which there are no 64-bit equivalents, so I have had to resort to using RunProgram to open a 32-bit exe that calls the DLL instead of just using OpenLibrary. Personally, however, if the anti-virus false positives were not such a big problem I would only offer 32-bit as there is no gain for my system using 64.
User avatar
skywalk
Addict
Addict
Posts: 4210
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

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

Post by skywalk »

Regardless of x86 or x64, you should know the size of your variables.
I use this cheat sheet. Maybe we can expand the data types with v6 :idea:

Code: Select all

Structure ScanAllTypes  ;-!PB Datatypes
  ; Allows 1 Define for all datatypes to be scanned.
  ; Define *p.ScanAllTypes = @somevariable or *somememory
  ; Consider as a StructureUnion. Takes no memory and overflow is not checked.
  ; Ex. *p\d[i] ; 'i' can be incremented in a loop without compiler error.
  ;          ; Type,   Bytes,  Min,                     Max,                     C Type
  b.b[0]     ; Byte,       1, -128,                     127,                     char, bool(C++)
  a.a[0]     ; Ascii,      1,  0,                       255,                     unsigned char, UCHAR, BYTE
  c.c[0]     ; Character,  2,  0,                       65535,                   unsigned short, USHORT
  u.u[0]     ; Unicode,    2,  0,                       65535,                   unsigned short, USHORT
  w.w[0]     ; Word,       2, -32768,                   32767,                   short, VB6 integer
  l.l[0]     ; Long,       4, -2147483648,              2147483647,              long, int (long & $FFFFFFFF = unsigned)
  ;;ul.ul[0] ; ULong,      4,  0,                       4294967295,              unsigned long, unsigned int, DWORD(C++)
  i.i[0]     ; Integer,    4, -2147483648,              2147483647,              long, int(x86 or 32-bit),sizeof*
  ;i.i[0]    ; Integer,    8, -9223372036854775808,     9223372036854775807,     long long(x64 or 64-bit),sizeof*
  q.q[0]     ; Quad,       8, -9223372036854775808,     9223372036854775807,     long long
  ;;uq.uq[0] ; UQuad,      8,  0,                       18446744073709551615,    unsigned long long, ULONGLONG
  f.f[0]     ; Float,      4,           -1.175494e-38,            3.402823e+38,  float      (6 decimal places)
  d.d[0]     ; Double,     8, -2.2250738585072013e-308, 1.7976931348623157e+308, double     (15 decimal places)
  ;;ld.ld[0] ; LDouble,   10,                -3.4e-4932,               1.1e+4932,long double(19 decimal places)
  ;;s.s      ; String$,    2/char + 2 for chr(0),       ,                        wchar_t, TCHAR
  ;s.s[0]    ; FAIL, -> *p = @x$, *p\s[0] = IMA ERROR.
  s.s{1}[0]  ; {FixedLen}, 2/char,                      ,                        char *, char var[] <-- Convert to Ascii
  ss.s[0]    ; Scan String array.
  ;s.s[0]    ; FAIL, -> *p = @x$(), *p\s[1],  *p\s[2],  etc.
  ;s.s[0]    ; OK,   -> *p = @x$,   *p\s[1],  *p\s[2],  etc.
  ;ss.s[0]   ; OK,   -> *p = @x$(), *p\ss[1], *p\ss[2], etc.
EndStructure
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
Allen
Enthusiast
Enthusiast
Posts: 103
Joined: Wed Nov 10, 2021 2:05 am

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

Post by Allen »

I found my mistake,

Below code work correctly in x64.

b.b=-123
w.w=-123
l.l=-123
i.i=-123

; when compare differnt type to decimal value
If b=-123:Debug "b is ok":EndIf
If w=-123:Debug "w is ok":EndIf
If l=-123:Debug "l is ok":EndIf
If i=-123:Debug "i is ok":EndIf

;when compare different type to hex value
If b=$FFFFFFFFFFFFFF85:Debug "b is ok":EndIf
If w=$FFFFFFFFFFFFFF85:Debug "w is ok":EndIf
If l=$FFFFFFFFFFFFFF85:Debug "l is ok":EndIf
If i=$FFFFFFFFFFFFFF85:Debug "i is ok":EndIf

If PeekB(@b)=$FFFFFFFFFFFFFF85:Debug "b is ok":EndIf
If PeekW(@w)=$FFFFFFFFFFFFFF85:Debug "w is ok":EndIf
If PeekL(@l)=$FFFFFFFFFFFFFF85:Debug "l is ok":EndIf
If PeekI(@i)=$FFFFFFFFFFFFFF85:Debug "i is ok":EndIf

In x64, when you compare with hex value, no matter what type( 1,2,4 or 8 byte) is on the left side, you always need to provide a 8 byte hex value on the right side. PeekB(@b) is definitely a single byte item, however you still need to use $FFFFFFFFFFFFFF85 , an eight byte hex value on the right side. In x86, you need to provide a 4 byte hex value.

To make my code work in x64, I need to modify the if line to "if l=$FFFFFFFFFFFFFF85". Originally I think I should always compare a long with a 4 byte hex value that is where I made the mistake.

I guess a type convertion to integer is performed before the comparsion. Eventhough I know the correct syntax now, I stil wish purebasic can accept equivalent length of hex value in comparsion, it seems more logical, compare a byte to a byte, a word to a word.

Thanks

Allen Wong
Post Reply