Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to adjust the code made for WINx86 to compile for WINx64

I was using assignment of Component Tag (NativeInt) value adding it to the set of bytes. The program worked properly when compiled for WIN32 but doesn't compile for WINx64. (Error 2001 Ordinal type required) Here is an MCVE:

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils, System.Classes;
  var 
  S:set of byte;
  C:TComponent;

begin
   C:=TComponent.Create(nil);
   C.Tag:=1;
   s:=[C.Tag];
   C.Free;
 end.

How can I adjust the code to make it suitable for WINx64 compilation?

like image 278
asd-tm Avatar asked Dec 06 '22 20:12

asd-tm


2 Answers

Tag is NativeInt. That is 32 bits in x86, and 64 bits in x64. As I understand it, a 32 bit integer is deemed to be an ordinal, and a 64 bit integer is not an ordinal. That is the reason for the compiler error, I think, although quite why Integer is deemed to be an ordinal type, and Int64 is not, I cannot tell you. If I had to guess, I would imagine that this is related to the fact that Int64 does not fit into a register on x86, and so requires quite different treatment from the compiler in comparison to 1, 2 and 4 byte ordinal types.

Since you probably don't want something that changes size, I expect you are fine to cast to Integer:

s := [Integer(C.Tag)];

And since you are only using the low 8 bits anyway, you should probably cast it to Byte:

s := [Byte(C.Tag)];

Preferably with an assertion that you are in range:

Assert((C.Tag >= low(Byte)) and (C.Tag <= high(Byte)))

Frankly though, you are, in my view, better avoiding Tag altogether. Store your data in a variable dedicated to the task, with a type that you can choose. As a general rule, in my view, Tag is something that you should avoid using. It's not type safe unless you happen to have a NatoiveInt to store, its name gives no indication of its contents, and it's all to easy to have collisions when multiple parties attempt to use it.

like image 76
David Heffernan Avatar answered Dec 08 '22 08:12

David Heffernan


Add a typecast of the Tag property to cast it to a Byte:

s:=[Byte(C.Tag)];

Although not necessary for the Win32 compiler it will accept this and it does allow the Win64 compiler to accept the code and has the same effect and result in both cases.

On the face of it this would appear to be a bug in the Win64 compiler as there is no apparent reason why it should require this cast.

like image 29
Deltics Avatar answered Dec 08 '22 09:12

Deltics