Reputation: 366
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?
Upvotes: 1
Views: 127
Reputation: 597896
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:
RSS-2077: PointerMath is broken for array types
Upvotes: 3
Reputation: 6174
PYMMQWords
is a Pointer
, not an Array
.
arrayFlags[currentFlag]
does not access an array, hence you cannot use indices here.^
) your pointer, e.g. arrayFlags^
to come from PYMMQWords
back to TYMMQWords
- then you can also use indices via arrayFlags^[currentFlag]
.Edit: so OP wanted this:
var arrayFlags: PYMMQWords; // Not just one TYMMQWords but many in a series. currentFlag: Integer; // Indicating which of those TYMMQWords he wants to access.
TYMMQWords
one would need to write arrayFlags^
to then access the 4 elements of that array.TYMMQWords
one would need to write (arrayFlags+ 2)^
to wander 2 times the size of TYMMQWords
with the pointer to then be able to access another instance of an array with 4 elements.In sum the overall code for access should be:
UInt64value:= (arrayFlags+ currentFlag)^[index0..3];
...with currentFlag
starting with 0
and being incremented as wanted.
Upvotes: -1