type helpers

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

type helpers

Free Pascal - General mailing list
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.


Mattias
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: type helpers

Michael Van Canneyt


On Fri, 11 Jan 2019, Mattias Gaertner via fpc-pascal wrote:

> 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?

Delphi acts the same, so for FPC: by design...

You will see that there are other pitfalls, for example when using helpers
on properties of type record. I have been bitten by this more than once.

Michael.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: type helpers

Free Pascal - General mailing list
In reply to this post by Free Pascal - General mailing list
Am Fr., 11. Jan. 2019, 11:24 hat Mattias Gaertner via fpc-pascal <[hidden email]> 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. 

Regards, 
Sven 

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: type helpers

Michael Van Canneyt


On Fri, 11 Jan 2019, Sven Barth via fpc-pascal wrote:

> Am Fr., 11. Jan. 2019, 11:24 hat Mattias Gaertner via fpc-pascal <
> [hidden email]> 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.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: type helpers

Free Pascal - General mailing list
In reply to this post by Free Pascal - General mailing list
On Fri, 11 Jan 2019 14:27:13 +0100
Sven Barth via fpc-pascal <[hidden email]> wrote:

>[...]
> 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

Ehm, in this case b.FW *does* changes.
Maybe you mean the case
  property W: word read GetW;
?

With a getter method indeed a temp variable is changed by the
helper.

> (same
> reason why the C operators do not work on properties). Same happens
> with constants btw: Word(42).DoIt will work as well.

Well, at least 3.DoIt is rejected.

Mattias



>
> Regards,
> Sven
>
> >  

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: type helpers

Free Pascal - General mailing list
Am Fr., 11. Jan. 2019, 14:52 hat Mattias Gaertner via fpc-pascal <[hidden email]> geschrieben:
On Fri, 11 Jan 2019 14:27:13 +0100
Sven Barth via fpc-pascal <[hidden email]> wrote:

>[...]
> 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

Ehm, in this case b.FW *does* changes.
Maybe you mean the case
  property W: word read GetW;
?

With a getter method indeed a temp variable is changed by the
helper.

Dang it. Seems I've missed that part of your example. In my opinion it should use a temp in that case. 


> (same
> reason why the C operators do not work on properties). Same happens
> with constants btw: Word(42).DoIt will work as well.

Well, at least 3.DoIt is rejected.

"3" is not a Word ;) 

Regards, 
Sven 

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal