Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2020-03

Property write access on records

9 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Ryan Joseph

In the snippet below why isn't it an error to write to a field of the read-only property? I was hoping this would give me some type safety but it just writes to a temp variable and does nothing. Not very helpful if you ask me.

=========================

type
  TSheet = record
      m_tableSize: TVec2i;
      function GetTableSize: TVec2i;
      property TableSize: TVec2i read GetTableSize;
  end;
var
  sheet: TSheet;
begin
  // why isn't this an error?
  sheet.x := 1;
end;

Regards,
Ryan Joseph

Reply by email

Sven Barth
to Ryan Joseph

Ryan Joseph via fpc-pascal schrieb am
Mo., 2. März 2020, 22:47:

Show quoted text 22 lines
In the snippet below why isn't it an error to write to a field of the read-only property? I was hoping this would give me some type safety but it just writes to a temp variable and does nothing. Not very helpful if you ask me. ========================= type TSheet = record m_tableSize: TVec2i; function GetTableSize: TVec2i; property TableSize: TVec2i read GetTableSize; end; var sheet: TSheet; begin // why isn't this an error? sheet.x := 1; end;

I assume you mean "sheet.TableSize.x"? Otherwise your example makes no sense...

In that case: you are working on a temporary copy of the record. It does not affect the TSheet instance anymore (that's essentially the same reason why C operators or var parameters are not allowed for properties).

Regards,
Sven

Reply by email

Ryan Joseph

I didn't get this reply on the mail list and just looked on the mail list archive and found it! Not sure what happened or if it's going to happen again.

Sven's reply:
===============

I assume you mean "sheet.TableSize.x"? Otherwise your example makes no sense...

In that case: you are working on a temporary copy of the record. It does not affect the TSheet instance anymore (that's essentially the same reason why C operators or var parameters are not allowed for properties).

===============

Yes, it's a temporary variable but doesn't it make sense to give an error because the property is read only? It's basically a no-op like it is now and defeats the purpose of read-only properties. It also creates a nasty bug because the programmer thinks they've written to something but they actually didn't.

Can we consider changing this behavior?

Regards,
Ryan Joseph

Reply by email

Jonas Maebe
to Ryan Joseph
Ryan Joseph wrote
Yes, it's a temporary variable but doesn't it make sense to give an error because the property is read only? It's basically a no-op like it is now and defeats the purpose of read-only properties. It also creates a nasty bug because the programmer thinks they've written to something but they actually didn't. Can we consider changing this behavior?

I think there is already an open bug report for this.

Jonas

Reply by email

Ryan Joseph
to Ryan Joseph: I didn't get this reply on the mail list and just looked on the mail list archive and…
On Mar 5, 2020, at 2:24 PM, Ryan Joseph wrote: Can we consider changing this behavior?

from https://lists.freepascal.org/pipermail/fpc-pascal/2020-March/057434.html

Ryan Joseph wrote

Yes, it's a temporary variable but doesn't it make sense to give an error because the property is read only? It's basically a no-op like it is now and defeats the purpose of read-only properties. It also creates a nasty bug because the programmer thinks they've written to something but they actually didn't.

I think there is already an open bug report for this.

Jonas

================

I looked on the bug tracker for "properties" and didn't see this so I'll make one but I wanted to confirm first it's not intended behavior. Jonas seems to hint that it is but Sven didn't mention it.

Regards,
Ryan Joseph

Reply by email

Sven Barth
to Ryan Joseph
Ryan Joseph wrote 19 lines
> On Mar 5, 2020, at 2:24 PM, Ryan Joseph wrote: > > Can we consider changing this behavior? from https://lists.freepascal.org/pipermail/fpc-pascal/2020-March/057434.html On 05/03/2020 08:24, Ryan Joseph via fpc-pascal wrote: Yes, it's a temporary variable but doesn't it make sense to give an error because the property is read only? It's basically a no-op like it is now and defeats the purpose of read-only properties. It also creates a nasty bug because the programmer thinks they've written to something but they actually didn't. > I think there is already an open bug report for this. Jonas ================ I looked on the bug tracker for "properties" and didn't see this so I'll make one but I wanted to confirm first it's not intended behavior. Jonas seems to hint that it is but Sven didn't mention it.

I've found two bug reports related to this (I searched for "property" and only those reports that are neither closed nor resolved):
- https://bugs.freepascal.org/view.php?id=23620
- https://bugs.freepascal.org/view.php?id=14534

And I noticed that the following already does generate an error:

=== code begin ===

program trecprop;
{$mode objfpc}
type
   TTestRec = record
     x: LongInt;
   end;

  { TTestClass }

   TTestClass = class(TObject)
   private
     fTestRec: TTestRec;
     function GetTestRec: TTestRec;
   public
     property Rec: TTestRec read fTestRec;
     property Rec2: TTestRec read GetTestRec;
   end;
var
   c: TTestClass;
function TTestClass.GetTestRec: TTestRec;
begin
   Result := fTestRec;
end;
begin
   c := TTestClass.Create;
   try
     c.Rec.x := 42;
     c.Rec2.x := 42;
   finally
     c.Free;
   end;
end.

=== code end ===

=== shell begin ===

PS C:\fpc\git> .\compiler\ppcx64.exe -n -Furtl\units\x86_64-win64 -viwn -FEtestoutput .\fpctests\trecprop.pp
Target OS: Win64 for x64
Compiling .\fpctests\trecprop.pp
trecprop.pp(32,10) Error: Argument cannot be assigned to trecprop.pp(33,11) Error: Argument cannot be assigned to trecprop.pp(38) Fatal: There were 2 errors compiling module, stopping Fatal: Compilation aborted

=== shell end ===

What currently does not generate an error is if you use a with-statement with the property (which is referenced by the bug reports).

So would you please provide a full example that shows your error? Cause if there is yet another case where the compiler does not generate an error where it should (aside from the with-statement) then this would be good to know.

Regards,
Sven

Reply by email

Ryan Joseph
to Sven Barth
Show quoted text 7 lines
On Mar 7, 2020, at 5:15 AM, Sven Barth wrote: I've found two bug reports related to this (I searched for "property" and only those reports that are neither closed nor resolved): - https://bugs.freepascal.org/view.php?id=23620 - https://bugs.freepascal.org/view.php?id=14534 And I noticed that the following already does generate an error:

Yes, you're right this does trigger the correct error. My example was actually bad because I didn't notice that my problem was coming from a more complex situation.

Given the code I get no error because the "width" property of the helper is writeable but the "point" property is read-only. This should still give the error because even though "width" is writable the "point" is read-only and the assignment will still go to temporary memory, thus failing silently.

Should I file a new bug report for this?

====================

{$mode objfpc}
{$modeswitch advancedrecords}
program test;
type
  TPoint = record
    x, y: integer;
  end;
type
  TSizeHelper = record helper for TPoint
    procedure SetWidth(newValue: integer); inline;
    procedure SetHeight(newValue: integer); inline;
    function GetWidth: integer; inline;
    function GetHeight: integer; inline;
    property Width: integer read GetWidth write SetWidth;
    property Height: integer read GetHeight write SetHeight;
  end;
procedure TSizeHelper.SetWidth(newValue: integer);
begin
  x := newValue;
end;
procedure TSizeHelper.SetHeight(newValue: integer);
begin
  y := newValue;
end;
function TSizeHelper.GetWidth: integer;
begin
  result := x;
end;
function TSizeHelper.GetHeight: integer;
begin
  result := y;
end;
type
  TThing = record
    m_point: TPoint;
    function GetPoint: TPoint;
    property point: TPoint read GetPoint;
  end;
function TThing.GetPoint: TPoint;
begin
  result := m_point;
end;
var
  t: TThing;
begin
  // no error!
  t.point.width := 0;
end.

Regards,
Ryan Joseph

Reply by email

Sven Barth
to Ryan Joseph

Ryan Joseph via fpc-pascal schrieb am
Sa., 7. März 2020, 05:18:

Show quoted text 24 lines
> On Mar 7, 2020, at 5:15 AM, Sven Barth wrote: > > I've found two bug reports related to this (I searched for "property" and only those reports that are neither closed nor resolved): > - https://bugs.freepascal.org/view.php?id=23620 > - https://bugs.freepascal.org/view.php?id=14534 > > And I noticed that the following already does generate an error: Yes, you're right this does trigger the correct error. My example was actually bad because I didn't notice that my problem was coming from a more complex situation. Given the code I get no error because the "width" property of the helper is writeable but the "point" property is read-only. This should still give the error because even though "width" is writable the "point" is read-only and the assignment will still go to temporary memory, thus failing silently. Should I file a new bug report for this?

Helpers indeed don't help there (pun intended :P). Please report, yes. And add a reference to the two bug reports I mentioned.

Regards,
Sven

Reply by email