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

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

我正在使用分配组件标记 (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.

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

添加 Tag 属性 的类型转换以将其转换为 Byte:

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

虽然 Win32 编译器不需要,但它会接受这个,它确实允许 Win64 编译器接受代码,并且在两种情况下具有相同的效果和结果。

从表面上看,这似乎是 Win64 编译器中的错误,因为没有明显的理由要求进行此转换。

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

因为你可能不想要改变大小的东西,我希望你可以转换为 Integer:

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

并且由于无论如何您只使用低 8 位,因此您可能应该将其转换为 Byte:

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

最好断言您在范围内:

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

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