动态数组长度的 32 位和 64 位不同类型?

32-bit and 64-bit different type for Length of dynamic array?

我有一个 DUnitX 测试套件 运行 在 Win32 上运行良好。但是当我尝试为 Win64 编译它时,这一行会产生编译错误:

Assert.AreEqual(4, Length(r.Values));

[dcc64 错误] ...:E2532 无法从方法 'AreEqual'[=29 的不同参数类型推断通用类型参数=]

r.Values 定义为:

Type TIntegers = TArray<Integer>

Assert.AreEqual 有不同的重载实现,dcc64 无法选择正确的实现...好吧,但为什么呢?为什么dcc32可以毫无问题地编译这个?

我唯一的线索是,如果我用鼠标悬停,Delphi 会告诉我长度是 System.Smallint 类型。没有 Assert.AreEqual 带有 Smallint 参数的实现...果然,如果我将它转换为 Integer,dcc64 将编译它。

但这让我很烦恼。如果我查看 System.pas 单元,我可以看到 DynArraySetLength 采用 NativeInt 参数......一个 64 位整数(我希望无符号,但不确定)。那么为什么 Length return 应该是一个 16 位有符号整数呢?这似乎是等待发生的麻烦,对吧?

我错过了什么?

在 64 位中,TArray 的长度类型为 Int64。据我所知,Int64 没有 AreEqual 重载,因此它尝试使用通用版本:AreEqual<>。但是从参数上看,好像不能判断是哪一个

所以在 Win64 中,执行:

 Assert.AreEqual<Int64>(4, Length(r.Values));

 Assert.AreEqual(4, Integer(Length(r.Values)));

后者当然是最简单的,因为它应该可以在 Win32 和 Win64 中运行,但可能无法处理非常大的数组。


FWIW,Length 没有 return Smallint。但是对于平台之间不同的函数,尤其是 "compiler magic" 函数,如 Length,这样的(错误的)信息可能会发生。这是 IDE 的问题,而不是编译器的问题。

更新:

正如@RemyLebeau 所说,使用 NativeInt 可能更容易。这应该适用于 Win32 和 Win64,因为 NativeInt 在 Win32 中是 Int32 而在 Win64 中是 Int64,它也是 _DynArrayLength returns:

Assert.AreEqual<NativeInt>(4, Length(r.Values));