This structure uses the so-called struct hack:
The ranges
element is a variable-length array placed inline in a struct. But you cannot encode this in a static C type. This is why you call the function to find out how much memory is allocated, and then the heap allocates the structure. If you allocated it on the stack or use SizeOf(...)
, then the structure will be too small.
The simplest task is to disable range checking for code that accesses ranges
. Although a type declaration says that only 0
is a valid index for ranges
, in fact, 0..cRanges-1
valid.
If you do not want to disable range checking for the corresponding code, then take a pointer to element 0, and then use pointer arithmetic in your loop.
var rng: PWCRange; .... rng := @GS.ranges[0]; for i:=0 to GS.cRanges-1 do begin // use rng^ inc(rng); end;
This, in my opinion, is the cleanest way to write code for sequential access. For random access and with range checking, you will need to declare some additional types to prevent range checking:
type TWCRangeArray = array [0..(MaxInt div SizeOf(TWCRange))-1] of TWCRange; PWCRangeArray = ^TWCRangeArray;
And then use type casting to access individual elements:
rng := PWCRangeArray(@GS.ranges)[i];
source share