Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I have a DUnitX test suite running fine on Win32. But when I try to compile it for Win64, this line produces a compilation error:

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

[dcc64 Error] ...: E2532 Couldn't infer generic type argument from different argument types for method 'AreEqual'

r.Values is defined as:

Type TIntegers = TArray<Integer>

Assert.AreEqual has different overloaded implementations and dcc64 can't choose the right one... ok, but why? And why can dcc32 compile this without a problem?

The only clue I have is that if I hover with the mouse, Delphi will tell me that Length is of type System.Smallint. There is no Assert.AreEqual implementation with Smallint parameters... and sure enough, if I cast it to Integer, dcc64 will compile it.

But this is bugging me a lot. If I look into the System.pas unit I can see that DynArraySetLength takes a NativeInt parameter... a 64 bit integer (I'd expect unsigned, but not sure about that). So why should Length return a 16 bit signed integer? That would seem like trouble waiting to happen, right?

What am I missing?

like image 637
Frazz Avatar asked Dec 24 '22 15:12

Frazz


1 Answers

In 64 bit, TArray has a length of type Int64. As far as I can tell, there is no AreEqual overload for Int64, so it tries to use the generic version: AreEqual<>. But it looks as if, from the parameters, it can't decide which one.

So in Win64, do:

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

or

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

The latter is of course the easiest, as it should work in Win32 and Win64, but may not be able to cope with very huge arrays.


FWIW, Length does not return a Smallint. But for functions that differ between platforms, especially "compiler magic" functions like Length, such (wrong) information can happen. That is a problem with the IDE, not with the compiler.

Update:

It may be easier, as @RemyLebeau said, to use NativeInt instead. That should work for both Win32 and Win64, as NativeInt is Int32 in Win32 and Int64 in Win64, and it is also what _DynArrayLength returns:

Assert.AreEqual<NativeInt>(4, Length(r.Values));
like image 118
Rudy Velthuis Avatar answered Mar 15 '23 21:03

Rudy Velthuis