Sign in Join

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

Mailing lists / fpc-devel / 2019-06

Is that supposed to work: property with "[var index: TFoo]" ?

17 messages · 7 people · –

Reply by email Subscribe to this list Your subscription

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

Martin

The below compiles, and writes
1 2

Are indexes to properties intentionally allowed to take "var param"? Btw it even compiles with an "out" param.

program Project1;
type

  { TFoo }

   TFoo = class
   private
     function GetFoo(var AIndex: Integer): Integer;
   public
     property Foo[var AIndex: Integer]: Integer read GetFoo;
   end;

{ TFoo }

function TFoo.GetFoo(var AIndex: Integer): Integer;
begin
   Result := AIndex;
   AIndex := AIndex+1;
end;
var a,i: integer;
   f: TFoo;
begin
   f := TFoo.Create;
   i := 1;
   a := f.Foo[i];
   writeln(a,' ',i);
   readln;
end.

Reply by email

Ryan Joseph
to Martin
Show quoted text 7 lines
On Jun 27, 2019, at 3:09 PM, Martin wrote: The below compiles, and writes 1 2 Are indexes to properties intentionally allowed to take "var param"? Btw it even compiles with an "out" param.

That sounds like a bug or something that should be prevented. I just found out default properties allowed overloading by accidental means so this may be another similar matter. Those should maybe be prevented also but that could break existing code.

Regards,
Ryan Joseph

Reply by email

Sven Barth
to Ryan Joseph

Ryan Joseph schrieb am Do., 27. Juni 2019, 23:50:

Show quoted text 15 lines
> On Jun 27, 2019, at 3:09 PM, Martin wrote: > > The below compiles, and writes > 1 2 > > Are indexes to properties intentionally allowed to take "var param"? > Btw it even compiles with an "out" param. That sounds like a bug or something that should be prevented. I just found out default properties allowed overloading by accidental means so this may be another similar matter. Those should maybe be prevented also but that could break existing code.

If it's a bug (what I do indeed think of this and the other bug you mentioned) it's considered acceptable to break backwards compatibility. After all we wouldn't be able to fix essentially anything as some code out there might rely on the behavior.

Regards,
Sven

Reply by email

Ryan Joseph
to Sven Barth
On Jun 27, 2019, at 5:57 PM, Sven Barth via fpc-devel wrote: If it's a bug (what I do indeed think of this and the other bug you mentioned) it's considered acceptable to break backwards compatibility. After all we wouldn't be able to fix essentially anything as some code out there might rely on the behavior.

Did you see the other users note in my bug report? Looks like this:

 tINIFile = object
  private
    procedure SetAsText( akey:PAnsiChar;val:PAnsiChar); overload;
    procedure SetAsText( asection,akey:PAnsiChar;val:PAnsiChar); overload;
    procedure SetAsText(ans,asection,akey:PAnsiChar;val:PAnsiChar); overload;
    function GetAsText( akey:PAnsiChar):PAnsiChar; overload;
    function GetAsText( asection,akey:PAnsiChar):PAnsiChar; overload;
    function GetAsText(ans,asection,akey:PAnsiChar):PAnsiChar; overload;
  public
    property Value [ans:PAnsiChar; asection:PAnsiChar; akey:PAnsiChar]:PAnsiChar
             read GetAsText write SetAsText; default;
  end;

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

Try it and play around but it works to call value with variable number of parameters.

Does that mean 2 bugs with properties then? allowing var and out in properties seems wrong also.

Regards,
Ryan Joseph

Reply by email

Martin Frb
to Ben Grasset
Ben Grasset wrote 10 lines
On Thu, Jun 27, 2019 at 4:12 PM Martin < > wrote: Are indexes to properties intentionally allowed to take "var param"? Btw it even compiles with an "out" param. "Var" and "Out" seem bad, although I've always though that "Constref" *should* be allowed.

Most property index are simple types. So you would not need it.

But *** hypothetically speaking ***  constref (and const too) could be given in the getter, but not in the property
TFoo = class
  private
    function GetFoo(constref AIndex: Integer): Integer;   public
    property Foo[AIndex: Integer]: Integer read GetFoo;   end;
The compiler woull simply (nothing is ever simple ;) ) need to know that the signature is still valid, even with the constref. Of course the compiler accepts any data type as valid for the index. So you could declare a big record for the index, and argue for constref. I don't really think it is needed.

Another one, that arises suspicion for its validity: open arrays. They can only be declared in parameter lists for procedures and functions. Oh and in properties:
TFoo = class
  private
    function GetFoo(AIndex: array of Integer): Integer;   public
    property Foo[AIndex: array of Integer]: Integer read GetFoo;   end;

Reply by email

Sven Barth
to Ryan Joseph: Did you see the other users note in my bug report? Looks like this: tINIFile = object…
Ryan Joseph wrote 26 lines
> On Jun 27, 2019, at 5:57 PM, Sven Barth via fpc-devel wrote: > > If it's a bug (what I do indeed think of this and the other bug you mentioned) it's considered acceptable to break backwards compatibility. After all we wouldn't be able to fix essentially anything as some code out there might rely on the behavior. > Did you see the other users note in my bug report? Looks like this: tINIFile = object private procedure SetAsText( akey:PAnsiChar;val:PAnsiChar); overload; procedure SetAsText( asection,akey:PAnsiChar;val:PAnsiChar); overload; procedure SetAsText(ans,asection,akey:PAnsiChar;val:PAnsiChar); overload; function GetAsText( akey:PAnsiChar):PAnsiChar; overload; function GetAsText( asection,akey:PAnsiChar):PAnsiChar; overload; function GetAsText(ans,asection,akey:PAnsiChar):PAnsiChar; overload; public property Value [ans:PAnsiChar; asection:PAnsiChar; akey:PAnsiChar]:PAnsiChar read GetAsText write SetAsText; default; end; ==================== Try it and play around but it works to call value with variable number of parameters. Does that mean 2 bugs with properties then? allowing var and out in properties seems wrong also.

That's what I meant with "the other bug you mentioned".

Regards,
Sven

Reply by email

Sven Barth
to Martin: The below compiles, and writes 1 2 Are indexes to properties intentionally allowed to…
Martin wrote 37 lines
The below compiles, and writes 1 2 Are indexes to properties intentionally allowed to take "var param"? Btw it even compiles with an "out" param. program Project1; type   { TFoo }   TFoo = class   private     function GetFoo(var AIndex: Integer): Integer;   public     property Foo[var AIndex: Integer]: Integer read GetFoo;   end; { TFoo } function TFoo.GetFoo(var AIndex: Integer): Integer; begin   Result := AIndex;   AIndex := AIndex+1; end; var a,i: integer;   f: TFoo; begin   f := TFoo.Create;   i := 1;   a := f.Foo[i];   writeln(a,' ',i);   readln; end.

I just tested with Delphi and it works there as well. So contrary to what we thought this does not seem to be a bug...

Regards,
Sven

Reply by email

Martin Frb
to Sven Barth
Sven Barth wrote 14 lines
Am 27.06.2019 um 21:09 schrieb Martin: > >   { TFoo } > >   TFoo = class >   private >     function GetFoo(var AIndex: Integer): Integer; >   public >     property Foo[var AIndex: Integer]: Integer read GetFoo; >   end; > > I just tested with Delphi and it works there as well. So contrary to what we thought this does not seem to be a bug...

What does Delphi do with

    property Foo[AIndex: Integer; BIndex: Integer = 0]: Integer read GetFoo;
Because FPC rejects this one. (And IMHO rightfully so)

Reply by email

Michael Van Canneyt
to John Lee

Yes temporarily, on purpose.

We were experiencing a DDOS attack using it.

Michael.

John Lee wrote 8 lines
URL for viewvc broken... svn.freepascal.org/cgi-bin/viewvc.cgi/?sortby=date#dirlist > >

Reply by email

Ryan Joseph
to Sven Barth: I just tested with Delphi and it works there as well. So contrary to what we thought this…
On Jun 28, 2019, at 1:39 AM, Sven Barth via fpc-devel wrote: I just tested with Delphi and it works there as well. So contrary to what we thought this does not seem to be a bug...

I think it’s still buggy. Why does this compile? I guess it would make sense if the property didn’t have any parameters and just mapped to any of the overloaded functions but with the parameters it doesn’t make any sense.

I submitted my patch for multiple default properties (https://bugs.freepascal.org/view.php?id=35772) which is a more sane solution than allowing this:

program test;
type
  tINIFile = object
  private
    function GetAsText( akey:integer):PAnsiChar; overload;
    function GetAsText(ans,asection,akey:PAnsiChar):PAnsiChar; overload;
  public
    property Value [ans:PAnsiChar; asection:PAnsiChar; akey:PAnsiChar]:PAnsiChar
             read GetAsText; default;
  end;
function tINIFile.GetAsText( akey:integer):PAnsiChar;
begin
end;
function tINIFile.GetAsText(ans,asection,akey:PAnsiChar):PAnsiChar;
begin
end;
var
  o: tINIFile;
  s: PAnsiChar;
begin
  s := o[1];
  s := o['a','b','c'];
end.

Regards,
Ryan Joseph

Reply by email

Sven Barth
to Ryan Joseph

Ryan Joseph schrieb am Fr., 28. Juni 2019, 20:12:

Show quoted text 12 lines
> On Jun 28, 2019, at 1:39 AM, Sven Barth via fpc-devel < > wrote: > > I just tested with Delphi and it works there as well. So contrary to what we thought this does not seem to be a bug... I think it’s still buggy. Why does this compile? I guess it would make sense if the property didn’t have any parameters and just mapped to any of the overloaded functions but with the parameters it doesn’t make any sense.

I was talking about the var/out stuff. The overload one doesn't work in Delphi either.

Regards,
Sven

Reply by email

Sven Barth
to Martin Frb: What does Delphi do with     property Foo[AIndex: Integer; BIndex: Integer = 0]:…
Martin Frb wrote 21 lines
On 28/06/2019 07:39, Sven Barth via fpc-devel wrote: > Am 27.06.2019 um 21:09 schrieb Martin: >> >>   { TFoo } >> >>   TFoo = class >>   private >>     function GetFoo(var AIndex: Integer): Integer; >>   public >>     property Foo[var AIndex: Integer]: Integer read GetFoo; >>   end; >> >> > I just tested with Delphi and it works there as well. So contrary to > what we thought this does not seem to be a bug... What does Delphi do with     property Foo[AIndex: Integer; BIndex: Integer = 0]: Integer read GetFoo; Because FPC rejects this one. (And IMHO rightfully so)

Assuming that GetFoo is declared as "function GetFoo(AIndex: Integer): Integer" It fails with "E2250: There is no overloaded variant of 'GetFoo' that can be called with these arguments" (or however that error message is translated to English.

The following also fails:

=== code begin ===

function GetFoo(AIndex: Integer; BIndex: Integer): Integer;
property Foo[AIndex: Integer; BIndex: Integer = 0]: Integer read GetFoo;

=== code end ===

However this works:

=== code begin ===

function GetFoo(AIndex: Integer; BIndex: Integer = 0): Integer;
property Foo[AIndex: Integer; BIndex: Integer = 0]: Integer read GetFoo;

=== code end ===

As does this:

=== code begin ===

function GetFoo(AIndex: Integer; BIndex: Integer = 0): Integer;
property Foo[AIndex: Integer; BIndex: Integer]: Integer read GetFoo;

=== code end ===

Regards,
Sven

Reply by email

Martin Frb
to Sven Barth
Sven Barth wrote 7 lines
Am 28.06.2019 um 10:39 schrieb Martin Frb: > What does Delphi do with > >     property Foo[AIndex: Integer; BIndex: Integer = 0]: Integer read > GetFoo; > Because FPC rejects this one. (And IMHO rightfully so)

Hope this madness can be avoided in fpc....

Show quoted text 5 lines
The following also fails: === code begin === function GetFoo(AIndex: Integer; BIndex: Integer): Integer; property Foo[AIndex: Integer; BIndex: Integer = 0]: Integer read GetFoo;

Good

Show quoted text 5 lines
However this works: === code begin === function GetFoo(AIndex: Integer; BIndex: Integer = 0): Integer; property Foo[AIndex: Integer; BIndex: Integer = 0]: Integer read GetFoo;

Ouch
What then about
  function GetFoo(AIndex: Integer = 0): Integer;
  property Foo[AIndex: Integer = 0]: Integer read GetFoo; And if it compiles, which of those can you call
  Obj.Foo
  Obj.Foo[]
And what if you make that default property....
  Obj[] // ????

Show quoted text 5 lines
As does this: === code begin === function GetFoo(AIndex: Integer; BIndex: Integer = 0): Integer; property Foo[AIndex: Integer; BIndex: Integer]: Integer read GetFoo;

This is ok.

GetFoo can be called directly.
So long, as the property will fail, if called with only one index.

Reply by email

Sven Barth
to Martin Frb
Martin Frb wrote 14 lines
> However this works: > === code begin === > > function GetFoo(AIndex: Integer; BIndex: Integer = 0): Integer; > property Foo[AIndex: Integer; BIndex: Integer = 0]: Integer read GetFoo; Ouch What then about   function GetFoo(AIndex: Integer = 0): Integer;   property Foo[AIndex: Integer = 0]: Integer read GetFoo; And if it compiles, which of those can you call   Obj.Foo   Obj.Foo[] And what if you make that default property....   Obj[] // ????

Those all don't compile. Even using my example above "Foo[42]" does not compile either, so while a default parameter can be declared the compiler won't allow the default parameters to be left out in the index clause.

Maybe we should forbid default parameters in the index clause in non-Delphi modes so that it's clear that this won't work?

Show quoted text 11 lines
> As does this: > === code begin === > > function GetFoo(AIndex: Integer; BIndex: Integer = 0): Integer; > property Foo[AIndex: Integer; BIndex: Integer]: Integer read GetFoo; This is ok. GetFoo can be called directly. So long, as the property will fail, if called with only one index.

Yes, it indeed fails.

Regards,
Sven

Reply by email

Michael Van Canneyt
to Sven Barth
Sven Barth wrote 23 lines
Am 30.06.2019 um 00:02 schrieb Martin Frb: >> However this works: >> === code begin === >> >> function GetFoo(AIndex: Integer; BIndex: Integer = 0): Integer; >> property Foo[AIndex: Integer; BIndex: Integer = 0]: Integer read GetFoo; > Ouch > What then about >   function GetFoo(AIndex: Integer = 0): Integer; >   property Foo[AIndex: Integer = 0]: Integer read GetFoo; > And if it compiles, which of those can you call >   Obj.Foo >   Obj.Foo[] > And what if you make that default property.... >   Obj[] // ???? Those all don't compile. Even using my example above "Foo[42]" does not compile either, so while a default parameter can be declared the compiler won't allow the default parameters to be left out in the index clause. Maybe we should forbid default parameters in the index clause in non-Delphi modes so that it's clear that this won't work?

It has no sense allowing them to be declared if they don't work, so yes. Either that or allow them to be omitted.

Michael.

Reply by email