[fpc-pascal] Read-only global references

Marcos Douglas md at delfire.net
Sun Mar 6 02:14:22 CET 2011


On Sat, Mar 5, 2011 at 7:05 PM, Mark Morgan Lloyd
<markMLl.fpc-pascal at telemetry.co.uk> wrote:
> Marcos Douglas wrote:
>>
>> On Sat, Mar 5, 2011 at 8:24 AM, Mark Morgan Lloyd
>> <markMLl.fpc-pascal at telemetry.co.uk> wrote:
>>>
>>> Where a unit exports an instance of an object, what's best practice for
>>> making this read-only? I'm referring to the object reference itself here,
>>> not properties of the object.
>>>
>>> Where I've done this in the past I've used a function:
>>>
>>> interface
>>>
>>> function InitText: TFormattedString;
>>>
>>> implementation
>>>
>>> var     xInitText: TFormattedString= nil;
>>>
>>> function InitText: TFormattedString;
>>>
>>> begin
>>>  result := xInitText
>>> end { InitText } ;
>>>
>>> Is there a better way using e.g. global properties that doesn't
>>> necessitate
>>> both a property and an explicit function?
>>>
>>> property InitText: TFormattedString read xInitText;
>>>
>>> The obvious problem here is that xInitText is a forward reference to an
>>> unexported variable.
>>
>> Make a function to return a global variable does not make it read only.
>> If I use your function like this:
>> o := InitText;
>> o := nil;  //this is the same xInitText = nil
>
> Disagree. You are changing the value of o, not of xInitText. xInitText is
> initialised once somewhere in the unit exporting it, subsequently its
> properties etc. can be used elsewhere e.g. InitText.AppendFormatted(...).

I was right.
The "o" points to "xInitText". If you release "o" the "xInitText" will
be release too.
But if you do:
o:=nil
...isn't the same xInitText:=nil, of course.

I did another test, see:

program test2;

{$mode objfpc}{$H+}

type
  pmyrec = ^myrec;
  myrec = record
    a: integer;
    p: pmyrec;
  end;

var
  r1: pmyrec;
  r2: pmyrec;
begin
  New(r1);
  r1^.a := 1;
  New(r1^.p);
  r1^.p^.a := 44;

  r2 := r1;
  r2^.a := 2;

  writeln(r2^.a);
  writeln(r2^.p^.a);

  Dispose(r1);
  writeln(r2^.a); //ok, because "a" is an simple integer

  writeln(r2^.p^.a); //  error, because "p" was released when "r1" was
relesead too.
  readln;
end.

I can access to primitive variables... but not to pointers.


Marcos Douglas



More information about the fpc-pascal mailing list