A r t i c l e s
Navigation

Note: This site is
a bit older, personal views
may have changed.

M a i n P a g e

D i r e c t o r y

Parameters Const Var and Pointers


Consider the following two programs, Program 1 first:
program Project1;
{$mode objfpc}{$H+}
type
  PSomeRec = ^TSomeRec;
  TSomeRec = record
    a: string;
    b: string;
  end;

// COPY OF POINTER IS ALLOCATED, PASSING BY VALUE
procedure ChangeRec1(Rec: PSomeRec);
begin
  new(Rec); // WRONG
  Rec^.a:= 'string A';
end;

var
  RecPtr: PSomeRec;

begin
  ChangeRec1(RecPtr);
  writeln(RecPtr^.a);
  dispose(RecPtr);
  readln;
end.

versus program 2 below:
program Project2;
{$mode objfpc}{$H+}
type
  PSomeRec = ^TSomeRec;
  TSomeRec = record
    a: string;
    b: string;
  end;

// COPY IS NOT ALLOCATED, PASSING BY REFERENCE
procedure ChangeRec1(var Rec: PSomeRec);
begin
  new(Rec); // OKAY TO DO
  Rec^.a:= 'string A';
end;

var
  RecPtr: PSomeRec;

begin
  ChangeRec1(RecPtr);
  writeln(RecPtr^.a);
  dispose(RecPtr); // okay because we are freeing the same reference
  readln;
end.


Now consider program 3 which still works but is not recommended:
program Project3;
{$mode objfpc}{$H+}
type
  PSomeRec = ^TSomeRec;
  TSomeRec = record
    a: string;
    b: string;
  end;

// COPY IS NOT ALLOCATED, PASSING BY REFERENCE
procedure ChangeRec1(const Rec: PSomeRec);
begin
  Rec^.a:= 'string A'; // you can access pointed to data, even if Rec is read-only
end;

var
  RecPtr: PSomeRec;

begin
  new(Rec); 
  ChangeRec1(RecPtr);
  writeln(RecPtr^.a);
  dispose(RecPtr);
  readln;
end.
Even though the Rec parameter is read-only, one can still access the fields inside the pointed to data. You may not however do this:
procedure ChangeRec1(const Rec: PSomeRec);
begin
  new(Rec); 
  Rec:= something; // can't do it, Rec *itself* is read only
end;
Nor can you do this and expect to pass the parameter out of the function:
procedure ChangeRec1(Rec: PSomeRec);
begin
  new(Rec); // allocating a local copy inside function! passed by value.
  Rec^.a:= 'string A';
  Rec:= Rec;
end; // Rec no longer available when function ends!

You must do it this way:
procedure ChangeRec1(var Rec: PSomeRec);
begin
  new(Rec); // allocating a local new copy, passed by value
  Rec^.a:= 'string A';
  Rec:= Rec;
end; // Rec is not a copy, and is available when function ends



About
This site is about programming and other things.
_ _ _