tw39332.pp 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. { %OPT=-O3 }
  2. {$mode objfpc} {$h+} {$typedaddress on}
  3. type
  4. pBaseType = ^BaseType;
  5. BaseType = uint32; // can be replaced with an arbitrary-sized array or record
  6. procedure Check(pstart, px: pBaseType; refIx: SizeInt; const desc: string);
  7. var
  8. ix: SizeInt;
  9. begin
  10. ix := px - pstart;
  11. writeln(desc, ' points at element #', ix);
  12. if ix = refIx then
  13. writeln('ok')
  14. else
  15. begin
  16. writeln('WRONG, must be #', refIx);
  17. halt(1);
  18. end;
  19. writeln;
  20. end;
  21. var
  22. x: array[0 .. 19] of BaseType;
  23. p: pBaseType;
  24. begin
  25. p := pBaseType(x);
  26. Check(p, p + 2, 2, 'p + 2');
  27. Check(p, p + 2 + 3, 5, 'p + 2 + 3');
  28. Check(p, p + 2 + 3 + 5, 10, 'p + 2 + 3 + 5');
  29. // These casts don't help.
  30. Check(p, pBaseType(pBaseType(p + 2) + 3) + 5, 10, 'pBaseType(pBaseType(p + 2) + 3) + 5');
  31. // These work, but prevent constant folding.
  32. Check(p, pBaseType(pointer(pBaseType(pointer(p + 2)) + 3)) + 5, 10, 'pBaseType(pointer(pBaseType(pointer(p + 2)) + 3)) + 5');
  33. Check(p, p + (2 + 3 + 5), 10, 'p + (2 + 3 + 5)');
  34. Check(p, p + 2 + 3 + 5 + 7, 17, 'p + 2 + 3 + 5 + 7');
  35. end.