[fpc-pascal] Read-only global references
Aleksa Todorovic
alexione at gmail.com
Sun Mar 6 08:20:41 CET 2011
On Sun, Mar 6, 2011 at 02:14, Marcos Douglas <md at delfire.net> wrote:
> 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
In fact, this is not ok. Here you access memory which has been freed,
so the result is completely undefined (hence difference between Delphi
and FPC in your example above).
>
> writeln(r2^.p^.a); // error, because "p" was released when "r1" was
> relesead too.
Just to be clear - memory pointed to by p has not been release, it is
still out there (you have to New-s and one Dispose), but you lost
reference to that memory because memory holding value of p was
released.
> readln;
> end.
>
> I can access to primitive variables... but not to pointers.
>
>
> Marcos Douglas
> _______________________________________________
> fpc-pascal maillist - fpc-pascal at lists.freepascal.org
> http://lists.freepascal.org/mailman/listinfo/fpc-pascal
>
More information about the fpc-pascal
mailing list