【问题标题】:32-bit and 64-bit different type for Length of dynamic array?动态数组长度的 32 位和 64 位不同类型?
【发布时间】:2017-08-02 09:09:39
【问题描述】:

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

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

[dcc64 错误] ...:E2532 无法从方法“AreEqual”的不同参数类型推断泛型类型参数

r.Values 定义为:

Type TIntegers = TArray<Integer>

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

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

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

我错过了什么?

【问题讨论】:

    标签: delphi delphi-10.1-berlin


    【解决方案1】:

    在 64 位中,TArray 的长度类型为 Int64。据我所知,Int64 没有 AreEqual 重载,因此它尝试使用通用版本:AreEqual&lt;&gt;。但看起来,从参数上看,它无法决定是哪一个。

    所以在 Win64 中,这样做:

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

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

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


    FWIW,Length 不返回 Smallint。但是对于平台之间不同的函数,尤其是像Length 这样的“编译器魔法”函数,可能会出现这样的(错误的)信息。这是 IDE 的问题,而不是编译器的问题。

    更新:

    正如@RemyLebeau 所说,改用NativeInt 可能更容易。这应该适用于 Win32 和 Win64,因为 NativeInt 在 Win32 中是 Int32 在 Win64 中是 Int64,这也是 _DynArrayLength 返回的内容:

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

    【讨论】:

    • 谢谢鲁迪。 IDE 中的 bug 比编译器中的好 :) 有趣的是,实际上在我的测试中,我将数组的大小与列表实现的 Count 进行比较,虽然前者是平台相关的,但后者是所有平台上的整数。现在我想知道为什么列表会以这种方式受到限制,因为它们在内部使用数组来保存元素。无论如何,我选择了通用形式,我更喜欢类型转换,因为它使断言更具可读性。我没有注意到 AreEqual 的过载。
    • 这并不是真正的过载。 AreEqualAreEqual&lt;&gt; 是不同的名字,只是看起来和我们人类很相似。
    • 感谢指正。我想补充一点,泛型版本 AreEqual 也可以在 Win32 和 Win64 中编译和工作(柏林 10.1,但泛型和 Int64 已经存在了一段时间)。
    • 我会改用Assert.AreEqual&lt;NativeInt&gt;(4, Length(r.Values))NativeInt 在 32 位中是 Integer,在 64 位中是 Int64。而System._DynArrayLength() 返回一个NativeInt
    • @Remy:很好! Rudy:所有 3 种解决方案实际上都适用于 Win32 和 Win64。剩下的唯一疑问是为什么 RTL 列表、列表助手和容器接口和实现没有转移到 NativeInt。它们在内部是基于数组的,但所有方法仍然引用整数容量、计数和索引参数:(
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-26
    • 1970-01-01
    • 1970-01-01
    • 2020-03-21
    相关资源
    最近更新 更多