如何调整为WINx86编译的代码为WINx64编译

asd*_*-tm 4 delphi win64 delphi-xe5

我正在使用Component Tag(NativeInt)值的赋值将其添加到字节集中.该程序在为WIN32编译时工作正常,但不为WINx64编译.(错误2001所需的序数类型)这是一个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.
Run Code Online (Sandbox Code Playgroud)

如何调整代码使其适合WINx64编译?

Dav*_*nan 8

TagNativeInt.这是x86中的32位,x64中的64位.据我了解,32位整数被认为是序数,64位整数不是序数.这就是编译器错误的原因,我认为,尽管为什么Integer被认为是一种序数类型,而Int64不是,我不能告诉你.如果我不得不猜测,我会想象这与Int64不适合x86上的寄存器的事实有关,因此与1,2和4字节序数类型相比,需要与编译器完全不同的处理.

既然你可能不想要改变大小的东西,我希望你可以投射到Integer:

s := [Integer(C.Tag)];
Run Code Online (Sandbox Code Playgroud)

既然你只使用低8位,你应该把它投射到Byte:

s := [Byte(C.Tag)];
Run Code Online (Sandbox Code Playgroud)

最好是断言你在范围内:

Assert((C.Tag >= low(Byte)) and (C.Tag <= high(Byte)))
Run Code Online (Sandbox Code Playgroud)

坦率地说,在我看来,你Tag完全避免了.将数据存储在专用于该任务的变量中,并使用您可以选择的类型.作为一般规则,在我看来,Tag是你应该避免使用的东西.它不是类型安全的,除非您碰巧有一个NatoiveInt存储,它的名称没有给出其内容的指示,并且当多方试图使用它时,很容易发生冲突.


Del*_*ics 7

添加Tag属性的类型转换以将其强制转换为字节:

s:=[Byte(C.Tag)];
Run Code Online (Sandbox Code Playgroud)

虽然Win32编译器不需要它,但它会接受这个并且它允许Win64编译器接受代码并且具有相同的效果并导致两种情况.

从表面上看,这似乎是Win64编译器中的一个错误,因为没有明显的理由为什么它需要这个强制转换.