A pointer of arrays is indexed once to get the array, then indexed again to get the element. This C-style trick should work with {$POINTERMATH ON}
, but it definitely doesn't:
{$POINTERMATH ON}
...
type
TYMMQWords = Array[0 .. 3] of UInt64;
PYMMQWords = ^TYMMQWords;
var
currentFlag: Integer;
temp: UInt64;
arrayFlags: PYMMQWords;
begin
temp := arrayFlags[currentFlag][0];
end;
Let's take it step by step:
arrayFlags[currentFlag]
is obviously a 4-element array of QWords. That's how pointer arithmetic works, and moreover, there is even no ambiguity here, this expression would simply give an error without {$POINTERMATH ON}
.arrayFlags[currentFlag][0]
, that is, (arrayFlags[currentFlag])[0]
, being an element of a QWord array, should denote a QWord element. No ambiguity, as well.However, Delphi gives a compiler error here:
Array type required
Where am I wrong?
This looks like a compiler bug. The compiler is simply not interpreting this code correctly when POINTERMATH
is used with a pointer to an array.
Here is another example that shows the problem is even worse:
{$POINTERMATH ON}
...
type
TYMMQWords = Array[0 .. 3] of UInt64;
PYMMQWords = ^TYMMQWords;
var
arr: array[0..3] of TYMMQWords;
currentFlag: Integer;
temp: TYMMQWords;
arrayFlags: PYMMQWords;
begin
arrayFlags := @arr[0];
currentFlag := 3;
temp := arrayFlags[currentFlag]; // ERROR
temp := (arrayFlags+currentFlag)^; // OK
end;
The compiler error is completely wrong:
E2010 Incompatible types: 'TYMMQWords' and 'UInt64'
Neither temp
nor arrayFlags[currentFlag]
are a UInt64
. arrayFlags
is a pointer to a TYMMQWords
, and so logically arrayFlags[currentFlag]
should yield (a reference to) a TYMMQWords
instance. But the compiler seems to think that indexing this pointer yields an element of the array rather than the array itself.
So, the Array type required
error makes more sense when taken in this context. In arrayFlags[currentFlag][0]
, the compiler is clearly trying to apply the [0]
to a UInt64
, not to a TYMMQWords
, hence the Array type required
error.
I have opened a bug ticket with Embarcadero: