Sign in Join

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

Mailing lists / fpc-pascal / 2011-11

various ways of passing a class instance as a parameter

7 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

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

Graeme Geldenhuys

Hi,

What exactly is the difference (if any) between the parameter modifier when you pass a class instance to a procedure?

In the example below, I can define foo() as follows...

procedure foo(AClass: TStringList);
  or
procedure foo(var AClass: TStringList);
  or
procedure foo(const AClass: TStringList);

...and the program output is always the same. As in the first case where I don't specify var or const, how does FPC treat the AClass parameter?

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
program a;
{$mode objfpc}{$H+}
uses
 Classes;
procedure foo(AClass: TStringList);
begin
  AClass.Add('inside foo');
end;
var
 sl: TStringList;
begin
  sl := TStringList.Create;
  try
    sl.Add('inside main');
    foo(sl);
    sl.Add('the end');
    writeln(sl.Text);
  finally
    sl.free;
  end;
end.
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

Here is the program output:

$ ./a
inside main
inside foo
the end

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

Reply by email

Alexander Shishkin
to Graeme Geldenhuys

15.11.2011 13:33, Graeme Geldenhuys пишет:

Show quoted text 5 lines
Hi, What exactly is the difference (if any) between the parameter modifier when you pass a class instance to a procedure?

I your example there is no difference, except that "var" could be ~0.01% slower

Reply by email

Martin Schreiber
to Graeme Geldenhuys: What exactly is the difference (if any) between the parameter modifier when you pass a…
Graeme Geldenhuys wrote 9 lines
Hi, What exactly is the difference (if any) between the parameter modifier when you pass a class instance to a procedure? In the example below, I can define foo() as follows... procedure foo(AClass: TStringList); or

Take a copy of the AClass instance pointer.

procedure foo(var AClass: TStringList);

Take the address of the instance variable. The instance pointer can be changed by the procedure, so the type of the instance variable must match TStringList exactly otherwise the procedure could store a wrong class into the instance variable. Example:

procedure foo(var AClass: TList);
begin
 aclass.free;
 aclass:= Tlist.create;
end;
[...]
var
 cl1: TStringList.
begin
 foo(cl1);       //does not compile
 //now there would be a TList in a TstringList variable
or procedure foo(const AClass: TStringList);

Take a copy of the AClass instance pointer, AClass is readonly.

or procedure foo(constref AClass: TStringList);

Take the address of the instance variable, AClass is readonly.

Martin

Reply by email

Graeme Geldenhuys
to Martin Schreiber
Martin Schreiber wrote

Thanks Martin. Extending my example by changing the body of foo() too...

  AClass.Free;
  AClass := TStringList.Create;
  AClass.Add('inside foo');

...reveals a bit more about the differences.

> procedure foo(const AClass: TStringList); > Take a copy of the AClass instance pointer, AClass is readonly.

This one confused me a bit. I thought the whole object would be read-only, but in fact it is just the AClass instance pointer which cannot be modified. The properties of AClass are still read-write.

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

Reply by email

Martin Schreiber
to Graeme Geldenhuys
Graeme Geldenhuys wrote 7 lines
>> procedure foo(const AClass: TStringList); > > Take a copy of the AClass instance pointer, AClass is readonly. This one confused me a bit. I thought the whole object would be read-only, but in fact it is just the AClass instance pointer which cannot be modified. The properties of AClass are still read-write.

The wording was bad. Should be:
"

procedure foo(AClass: TStringList); or

Take a copy of the AClass instance pointer.

procedure foo(var AClass: TStringList);

Take the address of the instance variable. The instance pointer pointed by the address can be changed by the procedure, so the type of the instance variable must match TStringList exactly otherwise the procedure could store a wrong class into the instance variable. Example:

procedure foo(var AClass: TList);
begin
 aclass.free;
 aclass:= Tlist.create;
end;
[...]
var
 cl1: TStringList.
begin
 foo(cl1);       //does not compile
 //now there would be a TList in a TstringList variable
or procedure foo(const AClass: TStringList);

Take a copy of the AClass instance pointer, AClass instance pointer is readonly.

or procedure foo(constref AClass: TStringList);

Take the address of the instance variable, AClass instance pointer pointed by the address is readonly.
"
Martin

Reply by email

Alexander Shishkin
to Graeme Geldenhuys: Thanks Martin. Extending my example by changing the body of foo() too... AClass.Free;…

15.11.2011 14:00, Graeme Geldenhuys пишет:

Show quoted text 6 lines
This one confused me a bit. I thought the whole object would be read-only, but in fact it is just the AClass instance pointer which cannot be modified. The properties of AClass are still read-write.

Perhaps it will be good to add support for const method modifier as in C++ and then make const class-instance parameters immutable.

Reply by email