Sign in Join

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

Mailing lists / fpc-pascal / 2011-11

parent class as a parameter type

17 messages · 8 people · –

Reply by email Subscribe to this list Your subscription

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

ik

Hello List,

Since 2.6.0, when you write something like this:

procedure foo(AClass : TStrings);
foo(MyStringList); // Will return an error that TStrings is expected ...

I can not use TStringList as the parameter without casting it to TStrings. But I do not understand why this limitation added. Can you please explain it to me ?

What can be done in order to make it supported again ? should it be declared as an abstract class or something ?

Thanks,
Ido

Reply by email

Sven Barth
to ik
ik wrote 8 lines
Since 2.6.0, when you write something like this: procedure foo(AClass : TStrings); foo(MyStringList); // Will return an error that TStrings is expected ... I can not use TStringList as the parameter without casting it to TStrings. But I do not understand why this limitation added. Can you please explain it to me ?

It works here with 2.6.0 RC1.

Can it be that you used "var" or "out"? Cause than this is expected: http://wiki.freepascal.org/User_Changes_2.6.0#Passing_derived_classes_to_var-_and_out-parameters

Regards,
Sven

Reply by email

Graeme Geldenhuys
to ik: Since 2.6.0, when you write something like this: procedure foo(AClass : TStrings);…
ik wrote
Since 2.6.0, when you write something like this:

I think it was even before this.

Show quoted text 6 lines
procedure foo(AClass : TStrings); foo(MyStringList); // Will return an error that TStrings is expected ... I can not use TStringList as the parameter without casting it to TStrings. But I do not understand why this limitation added. Can you please explain it to me ?

I ran into the exact same issue this week, and also can't understand why this is not allowed any more. It *is* allowed in Delphi (at least D7). Luckily I could change my code to TStringList to work around the problem.

So yes, if anybody could please explain what was the logic behind this crippling change?

The other issue I have is passing a property value via a var or const parameter. I used this a lot in my code too, and it worked for years without problems. This again, is supported in Delphi too. I have no idea why this was changed in FPC either. The work around looks damn stupid too. Declare a local variable and assign the property to it, then pass the local variable. In the end it has the same endresult, but just inconveniences to the developer with these unnecessary local variables.

Regards, - Graeme - _______________________________________________ fpGUI - a cross-platform Free Pascal GUI toolkit http://fpgui.sourceforge.net

Reply by email

Jonas Maebe
ik wrote
Since 2.6.0, when you write something like this: procedure foo(AClass : TStrings); foo(MyStringList); // Will return an error that TStrings is expected ...

Are you certain there is no "var" or "out" in front of that parameter?

I can not use TStringList as the parameter without casting it to TStrings. But I do not understand why this limitation added. Can you please explain it to me ?

In case of a var/out parameters: http://wiki.freepascal.org/User_Changes_2.6.0#Passing_derived_classes_to_var-_and_out-parameters

That page is also linked from the announcement mail and the readme.

Jonas

Reply by email

Jonas Maebe
to Graeme Geldenhuys: I think it was even before this. I ran into the exact same issue this week, and also…
Graeme Geldenhuys wrote 12 lines
On 12/11/2011, ik wrote: > > procedure foo(AClass : TStrings); > foo(MyStringList); // Will return an error that TStrings is expected ... > > I can not use TStringList as the parameter without casting it to TStrings. > But I do not understand why this limitation added. Can you please explain > it to me ? I ran into the exact same issue this week, and also can't understand why this is not allowed any more. It *is* allowed in Delphi (at least D7).

It's not allowed in Delphi in case of a var/out parameter. It's allowed in both FPC and Delphi in case of a value/const parameter.

The other issue I have is passing a property value via a var or const parameter. I used this a lot in my code too, and it worked for years without problems. This again, is supported in Delphi too.

No, it is not allowed by Delphi (at least not passing a property to a var-parameter; passing it to a const parameter is allowed by both FPC and Delphi).

Jonas

Reply by email

Felipe Monteiro de Carvalho
to Bart
Bart wrote
That would be strange indeed, because then most events (onclick handlers etc) would not compile anymore, since they are in the format procedure(Sender: TObject) of object...

It is not like that, he forgot adding var or out to the parameter. The example which you are mentioning has no var.

Felipe Monteiro de Carvalho

Reply by email

Graeme Geldenhuys
to Felipe Monteiro de Carvalho
Felipe Monteiro de Carvalho wrote 7 lines
On Tue, Nov 15, 2011 at 10:10 AM, Bart wrote: > That would be strange indeed, because then most events (onclick > handlers etc) would not compile anymore, since they are in the format > procedure(Sender: TObject) of object... It is not like that, he forgot adding var or out to the parameter. The example which you are mentioning has no var.

Indeed. I checked my code and Delphi 5-7 compatibility. The problem I had, wast that I specified those parameters as var.

Regards, - Graeme - _______________________________________________ fpGUI - a cross-platform Free Pascal GUI toolkit http://fpgui.sourceforge.net

Reply by email

ik
to Jonas Maebe: It's not allowed in Delphi in case of a var/out parameter. It's allowed in both FPC and…
Jonas Maebe wrote 21 lines
On 13 Nov 2011, at 17:56, Graeme Geldenhuys wrote: > On 12/11/2011, ik wrote: >> >> procedure foo(AClass : TStrings); >> foo(MyStringList); // Will return an error that TStrings is expected ... >> >> I can not use TStringList as the parameter without casting it to TStrings. >> But I do not understand why this limitation added. Can you please explain >> it to me ? > > I ran into the exact same issue this week, and also can't understand > why this is not allowed any more. It *is* allowed in Delphi (at least > D7). It's not allowed in Delphi in case of a var/out parameter. It's allowed in both FPC and Delphi in case of a value/const parameter.

Sorry for the late response, but why does out and var limit this issue ? I understand that it does, but not the reason for it.

Show quoted text 14 lines
> The other issue I have is passing a property value via a var or const > parameter. I used this a lot in my code too, and it worked for years > without problems. This again, is supported in Delphi too. No, it is not allowed by Delphi (at least not passing a property to a var-parameter; passing it to a const parameter is allowed by both FPC and Delphi). Jonas_______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply by email

ik
to Sven Barth
Sven Barth wrote 14 lines
Am 17.11.2011 09:23, schrieb ik: It's not allowed in Delphi in case of a var/out parameter. It's > allowed in both FPC and Delphi in case of a value/const parameter. > > > Sorry for the late response, but why does out and var limit this issue ? > I understand that it does, but not the reason for it. > The reason is mentioned in the link I sent you: http://wiki.freepascal.org/**User_Changes_2.6.0#Passing_** derived_classes_to_var-_and_**out-parameters<http://wiki.freepascal.org/User_Changes_2.6.0#Passing_derived_classes_to_var-_and_out-parameters>

I read it, but I do not understand it.

TStrings is a class. TStringList is a class inherited from TStrings. How does it prevent the type checking ?
As I remember, if I placed there "TFom" based class, it will not like it and report and error. That's why I do not understand it I guess.

Show quoted text 9 lines
Regards, Sven ______________________________**_________________ fpc-pascal maillist - http://lists.freepascal.org/**mailman/listinfo/fpc-pascal<http://lists.freepascal.org/mailman/listinfo/fpc-pascal>

Reply by email

Sven Barth
to ik
ik wrote 26 lines
On Thu, Nov 17, 2011 at 16:03, Sven Barth < > wrote: Am 17.11.2011 09:23, schrieb ik: It's not allowed in Delphi in case of a var/out parameter. It's allowed in both FPC and Delphi in case of a value/const parameter. Sorry for the late response, but why does out and var limit this issue ? I understand that it does, but not the reason for it. The reason is mentioned in the link I sent you: http://wiki.freepascal.org/__User_Changes_2.6.0#Passing___derived_classes_to_var-_and___out-parameters <http://wiki.freepascal.org/User_Changes_2.6.0#Passing_derived_classes_to_var-_and_out-parameters> I read it, but I do not understand it. TStrings is a class. TStringList is a class inherited from TStrings. How does it prevent the type checking ? As I remember, if I placed there "TFom" based class, it will not like it and report and error. That's why I do not understand it I guess.

Emagine the following code:

procedure Foo(var aList: TStrings);
begin
   aList.Free;
   aList := TStrings.Create;
end;
var
   l: TStringList;
begin
   l := TStringList.Create;
   Foo(l);
   l.Sort;
end.

When you run this code you will have a big problem. Your "l" variable is a TStringList, but after calling Foo your variable holds a TStrings instance (which is lower in the hierarchy than TStringList)! If you now call Sort you will get an access violation if you're lucky or some strange error if not, because Sort is introduced by TStringList. Thus you call into "nothing" when executing this on a TStrings.

Is the reason why this is forbidden more clear now?

Regards,
Sven

Reply by email

ik
to Sven Barth
Sven Barth wrote 59 lines
Am 17.11.2011 15:07, schrieb ik: > On Thu, Nov 17, 2011 at 16:03, Sven Barth < > < >> > wrote: > > Am 17.11.2011 09:23, schrieb ik: > > It's not allowed in Delphi in case of a var/out parameter. It's > allowed in both FPC and Delphi in case of a value/const > parameter. > > > Sorry for the late response, but why does out and var limit this > issue ? > I understand that it does, but not the reason for it. > > > The reason is mentioned in the link I sent you: > http://wiki.freepascal.org/__**User_Changes_2.6.0#Passing___** > derived_classes_to_var-_and___**out-parameters<http://wiki.freepascal.org/__User_Changes_2.6.0#Passing___derived_classes_to_var-_and___out-parameters> > > <http://wiki.freepascal.org/**User_Changes_2.6.0#Passing_** > derived_classes_to_var-_and_**out-parameters<http://wiki.freepascal.org/User_Changes_2.6.0#Passing_derived_classes_to_var-_and_out-parameters> > > > > > I read it, but I do not understand it. > > TStrings is a class. TStringList is a class inherited from TStrings. How > does it prevent the type checking ? > As I remember, if I placed there "TFom" based class, it will not like it > and report and error. That's why I do not understand it I guess. > Emagine the following code: procedure Foo(var aList: TStrings); begin aList.Free; aList := TStrings.Create; end; var l: TStringList; begin l := TStringList.Create; Foo(l); l.Sort; end. When you run this code you will have a big problem. Your "l" variable is a TStringList, but after calling Foo your variable holds a TStrings instance (which is lower in the hierarchy than TStringList)! If you now call Sort you will get an access violation if you're lucky or some strange error if not, because Sort is introduced by TStringList. Thus you call into "nothing" when executing this on a TStrings. Is the reason why this is forbidden more clear now?

‏Yes, thank you

Show quoted text 9 lines
Regards, Sven ______________________________**_________________ fpc-pascal maillist - http://lists.freepascal.org/**mailman/listinfo/fpc-pascal<http://lists.freepascal.org/mailman/listinfo/fpc-pascal>

Reply by email

Mattias Gaertner
to Sven Barth: Emagine the following code: procedure Foo(var aList: TStrings); begin aList.Free; aList…
Show quoted text 52 lines
Am 17.11.2011 15:07, schrieb ik: > On Thu, Nov 17, 2011 at 16:03, Sven Barth < > > wrote: > > Am 17.11.2011 09:23, schrieb ik: > > It's not allowed in Delphi in case of a var/out parameter. It's > allowed in both FPC and Delphi in case of a value/const > parameter. > > > Sorry for the late response, but why does out and var limit this > issue ? > I understand that it does, but not the reason for it. > > > The reason is mentioned in the link I sent you: > http://wiki.freepascal.org/__User_Changes_2.6.0#Passing___derived_classes_to_var-_and___out-parameters > <http://wiki.freepascal.org/User_Changes_2.6.0#Passing_derived_classes_to_var-_and_out-parameters> > > > I read it, but I do not understand it. > > TStrings is a class. TStringList is a class inherited from TStrings. How > does it prevent the type checking ? > As I remember, if I placed there "TFom" based class, it will not like it > and report and error. That's why I do not understand it I guess. Emagine the following code: procedure Foo(var aList: TStrings); begin aList.Free; aList := TStrings.Create; end; var l: TStringList; begin l := TStringList.Create; Foo(l); l.Sort; end. When you run this code you will have a big problem. Your "l" variable is a TStringList, but after calling Foo your variable holds a TStrings instance (which is lower in the hierarchy than TStringList)! If you now call Sort you will get an access violation if you're lucky or some strange error if not, because Sort is introduced by TStringList. Thus you call into "nothing" when executing this on a TStrings. Is the reason why this is forbidden more clear now?

The l.Sort is the important line, that is missing in the wiki example.

Maybe this example can replace the example in the wiki?

Mattias

Reply by email

Sven Barth
to Mattias Gaertner
Mattias Gaertner wrote 31 lines
On Thu, 17 Nov 2011 15:15:46 +0100 Sven Barth wrote: > > Emagine the following code: > > procedure Foo(var aList: TStrings); > begin > aList.Free; > aList := TStrings.Create; > end; > > var > l: TStringList; > begin > l := TStringList.Create; > Foo(l); > l.Sort; > end. > > When you run this code you will have a big problem. Your "l" variable is > a TStringList, but after calling Foo your variable holds a TStrings > instance (which is lower in the hierarchy than TStringList)! If you now > call Sort you will get an access violation if you're lucky or some > strange error if not, because Sort is introduced by TStringList. Thus > you call into "nothing" when executing this on a TStrings. > > Is the reason why this is forbidden more clear now? The l.Sort is the important line, that is missing in the wiki example. Maybe this example can replace the example in the wiki?

I have extended the example in the wiki a bit in the hope to clarify the seriousness of this issue.

Regards,
Sven

Reply by email