Sven Barth wrote 48 lines
Am Fr., 11. Jan. 2019, 11:24 hat Mattias Gaertner via fpc-pascal <
> geschrieben:
> Hi,
>
> A type helper can change Self.
> I wondered how FPC 3.3.1 handles properties and got some
> unexpected results. Is this by design, a bug, or not-yet-implemented?
>
> {$mode objfpc}{$modeswitch typehelpers}
> type
> TIntHlp = type helper for word
> procedure DoIt;
> end;
>
> TBig = class
> strict private
> FW: word;
> procedure SetW(const AValue: word);
> public
> property W: word read FW write SetW;
> end;
>
> var b: TBird;
>
> procedure TBig.SetW(const AValue: word);
> begin
> // not called by type helper
> writeln('TBig.SetW');
> end;
>
> procedure TIntHlp.DoIt;
> begin
> writeln('TIntHlp.DoIt START ',Self,' w=',b.w);
> Self:=4; // changes b.FW directly
> writeln('TIntHlp.DoIt END ',Self,' w=',b.w);
> end;
>
> begin
> b:=TBig.Create;
> b.w.DoIt;
> end.
>
This is by design. In this case DoIt is called on a temp variable that gets
its value from b.w, the value of b.FW does not change (same reason why the
C operators do not work on properties). Same happens with constants btw:
Word(42).DoIt will work as well.
IMO It makes sense to forbid this.
For simple types and records, writing to self means self is treated like a var parameter (i.e. there is an address). The compiler can detect this.
For properties there is no address (it cannot be used as var param), so treating self as a var parameter would automatically forbid writing using a method - that writes to self - on a property.
The behaviour to make a copy has bitten me more than once, and I would much prefer that the compiler simply does not allow me to do something which will guaranteed not give me what I was expecting.
Michael.