Another Delphi mode question :) -- classes as parameter

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

Another Delphi mode question :) -- classes as parameter

Alexandre Leclerc
I tried the following:

procedure ThisAndThat(bitmap: TBitmap);
begin
  if not Assigned(bitmap) then
    bitmap := TBitmap.Create;
end;

function Test: boolean;
var
  bitmap: TBitmap;
begin
  bitmap := nil;
  ThisAndThat(bitmap);
  Result := Assigned(bitmap);
  bitmap.Free;
end;

In Delphi a class is always treated as a 'var' when passed in a
function since a class is a pointer to actual data; logical but
confusing when begining in Delphi. So in Delphi Test() would return
true. I made a function like this in Lazarus and I see that it's not
working. This behave as a local copy of the class! Now in FPC I
changed the procedure for:
    procedure ThisAndThat(var bitmap: TBitmap);
and this is working.

The question: I guess this is an other delphi mode thing?
Is there a page with all these Delphi mode / FPC differences? I'll
check the wiki right after.

I prefer the behaviour of FPC because it is consistent, but is it
really a copy a of class?!?. Since my background, I'll have to check
all my functions that have classes in parameters to make sure this is
working as expected.

Best regards.

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

Re: Another Delphi mode question :) -- classes as parameter

Michael Van Canneyt


On Wed, 12 Jul 2006, Alexandre Leclerc wrote:

> I tried the following:
>
> procedure ThisAndThat(bitmap: TBitmap);
> begin
> if not Assigned(bitmap) then
>   bitmap := TBitmap.Create;
> end;
>
> function Test: boolean;
> var
> bitmap: TBitmap;
> begin
> bitmap := nil;
> ThisAndThat(bitmap);
> Result := Assigned(bitmap);
> bitmap.Free;
> end;
>
> In Delphi a class is always treated as a 'var' when passed in a
> function since a class is a pointer to actual data; logical but
> confusing when begining in Delphi. So in Delphi Test() would return
> true.

Ahem.

Have you tried that ? Because it is manifestly NOT true:

-----------------------------------------------------------------------
procedure TForm2.DoTest(S : TStrings);

begin
   S:=TStringList.Create;
end;

procedure TForm2.WisaButton1Click(Sender: TObject);
Var
   S : TSTrings;

begin
   S:=Nil;
   DoTest(S);
   If S=Nil then
     ShowMessage('S still nil')
   else
     ShowMessage('S assigned');
end;
-----------------------------------------------------------------------

Shows 'S still nil'.

What is more, it gives a warning for the dotest method:

   [Hint] frmmain.pas(44): Value assigned to 'S' never used

What IS true is that you can change the properties of S, even if it is
passed by value or as const. But the pointer S cannot be changed.

So FPC is perfectly compliant.

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

Re: Another Delphi mode question :) -- classes as parameter

Felipe Monteiro de Carvalho
In reply to this post by Alexandre Leclerc
On 7/12/06, Alexandre Leclerc <[hidden email]> wrote:
> In Delphi a class is always treated as a 'var' when passed in a
> function since a class is a pointer to actual data;

No, not really. It is always passed as a pointer, but here you want to
change the pointer and not the contents of the class. So when you put
a class as var you are passing a pointer to the pointer.

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

Re: Another Delphi mode question :) -- classes as parameter

Alexandre Leclerc
In reply to this post by Michael Van Canneyt
2006/7/12, Michael Van Canneyt <[hidden email]>:
> Ahem.
>
> Have you tried that ? Because it is manifestly NOT true:

Ah! I learnd something today! You are completly correct:

> What IS true is that you can change the properties of S, even if it is
> passed by value or as const. But the pointer S cannot be changed.

I desired to change the pointer; manifestly I have to pass it as var.

> What is more, it gives a warning for the dotest method:
>
>    [Hint] frmmain.pas(44): Value assigned to 'S' never used

There are so many hints that I'm not reading them anymore. (I found
that sometimes hints where kind of useless... For example, the
implementation of a form event OnKeyDown will generate a hint "Hint:
Parameter "Shift" not used" if I do not use this one parameter... but
I don't care about that and can't do nothing about it. This is not a
hint, this is obivious; this makes noise in the messages. So when you
have many functions/procedures/events like this, you have a plethora
of "useless" hint. So I do not check them anymore... It take too much
time to parse them all and get the relevent one.)

(By the way, can GetLongOpts have the parameter 'out' instead of 'var
Longind: Longint' this would avoid another hint about the variable not
initialized (it is useless to init the var since this is out only)...
unless 'out' does not allow 'nil').

> So FPC is perfectly compliant.

Yes, thank you for this. Best regards.

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

Re: Another Delphi mode question :) -- classes as parameter

Alexandre Leclerc
In reply to this post by Felipe Monteiro de Carvalho
2006/7/12, Felipe Monteiro de Carvalho <[hidden email]>:
> On 7/12/06, Alexandre Leclerc <[hidden email]> wrote:
> > In Delphi a class is always treated as a 'var' when passed in a
> > function since a class is a pointer to actual data;
>
> No, not really. It is always passed as a pointer, but here you want to
> change the pointer and not the contents of the class. So when you put
> a class as var you are passing a pointer to the pointer.

Yes, it is really an error from myself. Thanks.

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

Re: Another Delphi mode question :) -- classes as parameter

Matt Emson
In reply to this post by Alexandre Leclerc
>> What IS true is that you can change the properties of S, even if it is
>> passed by value or as const. But the pointer S cannot be changed.
>
> I desired to change the pointer; manifestly I have to pass it as var.

Be aware that if you do this, you will lose the ability to pass any class
that descends from the param type. Var params have to be the smae type
exactly. The Delphi compiler will halt on an error if the exact type isn't
used (though, thinking about it, the "Strict var params" switch might
loosen this in Delphi..)

Best advice: Don't use var params for initialization. Either return the
instance of the class - and raise an exception if there is an error, or
use 'out' params, as it makes your intention clearer.

M


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

Re: Another Delphi mode question :) -- classes as parameter

Alexandre Leclerc
2006/7/13, memsom <[hidden email]>:
> Be aware that if you do this, you will lose the ability to pass any class
> that descends from the param type. Var params have to be the smae type
> exactly. The Delphi compiler will halt on an error if the exact type isn't
> used (though, thinking about it, the "Strict var params" switch might
> loosen this in Delphi..)

Thank you for the information. I did not know that.

> Best advice: Don't use var params for initialization. Either return the
> instance of the class - and raise an exception if there is an error, or
> use 'out' params, as it makes your intention clearer.

It made me revise my code and I'm able to do what you suggest. This is
a better approach that I usually take, but I took this code from an
example on VirtualTreeView and in order to test quickly I simply took
it like that. Now I'll remake the procedure into a function.

Best regards.

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