1234567891011121314151617181920212223242526272829303132333435363738394041 |
- { %OPT=-O3 }
- {$mode objfpc} {$h+} {$typedaddress on}
- type
- pBaseType = ^BaseType;
- BaseType = uint32; // can be replaced with an arbitrary-sized array or record
- procedure Check(pstart, px: pBaseType; refIx: SizeInt; const desc: string);
- var
- ix: SizeInt;
- begin
- ix := px - pstart;
- writeln(desc, ' points at element #', ix);
- if ix = refIx then
- writeln('ok')
- else
- begin
- writeln('WRONG, must be #', refIx);
- halt(1);
- end;
- writeln;
- end;
- var
- x: array[0 .. 19] of BaseType;
- p: pBaseType;
- begin
- p := pBaseType(x);
- Check(p, p + 2, 2, 'p + 2');
- Check(p, p + 2 + 3, 5, 'p + 2 + 3');
- Check(p, p + 2 + 3 + 5, 10, 'p + 2 + 3 + 5');
- // These casts don't help.
- Check(p, pBaseType(pBaseType(p + 2) + 3) + 5, 10, 'pBaseType(pBaseType(p + 2) + 3) + 5');
- // These work, but prevent constant folding.
- Check(p, pBaseType(pointer(pBaseType(pointer(p + 2)) + 3)) + 5, 10, 'pBaseType(pointer(pBaseType(pointer(p + 2)) + 3)) + 5');
- Check(p, p + (2 + 3 + 5), 10, 'p + (2 + 3 + 5)');
- Check(p, p + 2 + 3 + 5 + 7, 17, 'p + 2 + 3 + 5 + 7');
- end.
|