Pointer Math (Delphi)

From RAD Studio
Jump to: navigation, search

Go Up to Delphi Compiler Directives (List) Index


Type

Switch

Syntax

{$POINTERMATH ON} or {$POINTERMATH OFF}

Default

{$POINTERMATH OFF}

Scope

Local

Remarks

Pointer math is simply treating any given typed pointer in some narrow instances as a scaled ordinal where you can perform simple arithmetic operations directly on the pointer variable. It also allows you to treat such a pointer variable as an unbounded array using the array [] operator. Notice in the example above that incrementing the index of an array of a type is equivalent to incrementing a pointer to that type. An increment of one bumps the pointer by the size an array element in bytes, not by one byte.

The POINTERMATH directive has a local scope. That is, if you turn this directive ON and do not turn it off in the module, it will remain on only until the end of the module. Also, if you declare a typed pointer with this directive ON, any variable of that type allows scaled pointer arithmetic and array indexing, even after the directive has been turned OFF Similarly, any block of code surrounded by this directive allows arithmetic operations for ANY typed pointers within the block regardless of whether the typed pointer was originally declared with POINTERMATH ON.

This directive affects only typed pointers. Variables of type Pointer do not allow the pointer math features, since type Pointer is effectively pointing to a void element, which is 0 bytes in size. Untyped var or const parameters are not affected because they are not really pointers.

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Memo1: TMemo;
    CheckBox1: TCheckBox;
    ListBox1: TListBox;
    ComboBox1: TComboBox;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

type
  Rects = ^TRect;
  RectList = array[0..10] of TRect;
var
  Form1: TForm1;
  myRects: Rects;
  myRectList : RectList;
  procedure ListRect(Rect: TRect);
  procedure ListRects(PRects: Rects; Count: Integer);
  procedure ReadRects;
  procedure WriteRects;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  ListRects(myRects, Form1.ComponentCount);
end;

procedure ListRect(Rect: TRect);
begin
  Form1.ListBox1.Items.Add(
    'BoundsRect: Left: ' + IntToStr(Rect.Left) +
    ' Right: ' + IntToStr(Rect.Right) +
    ' Top: ' + IntToStr(Rect.Top) +
    ' Bottom: ' + IntToStr(Rect.Bottom));
end;

{$POINTERMATH ON}
procedure ListRects(PRects: Rects; Count: Integer);
begin
  while Count > 0 do
  begin
    ListRect(PRects[Count - 1]); // This line will not compile without Tiburon.
//    ListRect((PRects + Count - 1)^); // Neither will this line.
    Dec(Count);
  end;
end;

procedure ReadRects;
var
  I, index : Integer;
  Temp: TWinControl;
begin
{$T-}
  index := 0;
  for I := Form1.ComponentCount - 1 downto 0 do
  begin
    if (Form1.Components[I] is TWinControl) then
    begin
      Temp := TWinControl(Form1.Components[I]);
      myRectList[index] := Temp.BoundsRect;
      index := index + 1;
    end;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  myRects := Addr(myRectList);
  ReadRects;
end;