Board index » delphi » pointer vs. var parameter

pointer vs. var parameter

Hi,
(sorry for the english)

As far I tought that I understood the way the pointers are handled in
Delphi.
I now face a problem with them. Help.

I use some kind of controler object to deconnect the creation of an object.
Lets say:

unit Data
interface
var
  MyList: TStringList;
...
end;

unit Controler
interface
  procedure CreateList(aList: TStringList);
implementation
  procedure CreateList(aList: TStringList);
  begin
    aList := TStringList.Create;
  end;
...
end.

unit Main;
...
  Contoler.CreateList(Data.MyList);
...
end.

This won't work (MyList will be kept to nil) if I don't declare the aList
parameter as VAR aList.
What's the problem?
The aList object isn't pushed on the stack. A pointer is a pointer is a
pointer!
I can modify any VCL object passed in parameter without qualifying it as a
pointer to a pointer (var).

It seems so a basic issue.... help...

Clement

 

Re:pointer vs. var parameter


TStringList is an object. An object is some memory.
An object variable is a pointer which points to the object memory.
you want to assign the object variable with some new object.
Therefore you have to use var. var silently delivers the address
(pointer to) of the variable. Usage of the var param name (assignment)
silently dereferences this address/pointer.
Clement Boucher schrieb:
Quote

> Hi,
> (sorry for the english)

> As far I tought that I understood the way the pointers are handled in
> Delphi.
> I now face a problem with them. Help.

> I use some kind of controler object to deconnect the creation of an object.
> Lets say:

> unit Data
> interface
> var
>   MyList: TStringList;
> ...
> end;

> unit Controler
> interface
>   procedure CreateList(aList: TStringList);
> implementation
>   procedure CreateList(aList: TStringList);
>   begin
>     aList := TStringList.Create;
>   end;
> ...
> end.

> unit Main;
> ...
>   Contoler.CreateList(Data.MyList);
> ...
> end.

> This won't work (MyList will be kept to nil) if I don't declare the aList
> parameter as VAR aList.
> What's the problem?
> The aList object isn't pushed on the stack. A pointer is a pointer is a
> pointer!
> I can modify any VCL object passed in parameter without qualifying it as a
> pointer to a pointer (var).

> It seems so a basic issue.... help...

> Clement

Re:pointer vs. var parameter


Hi Robert,

I'm aware that a object variable is a pointer to some memory used by/for the
object type.
There is however a point that I don't understand.  I can change one of the
object property, by defenrencing
the pointer passed as a parameter by value but I can't assign a new memory
address to the same parameter.

Based on what you said I've made a test.
I used the CreateList method with a parameter without the var qualifier but
I passed the parameter as
@Data.MyList. Same result.

All this seems to be finally linked to the assignment (:=) operator. Am I
right?

Clement

Robert Marquardt <robert_marqua...@gmx.de> a crit dans le message :
38E9F353.2BF7...@gmx.de...

Quote
> TStringList is an object. An object is some memory.
> An object variable is a pointer which points to the object memory.
> you want to assign the object variable with some new object.
> Therefore you have to use var. var silently delivers the address
> (pointer to) of the variable. Usage of the var param name (assignment)
> silently dereferences this address/pointer.

> Clement Boucher schrieb:

> > Hi,
> > (sorry for the english)

> > As far I tought that I understood the way the pointers are handled in
> > Delphi.
> > I now face a problem with them. Help.

> > I use some kind of controler object to deconnect the creation of an
object.
> > Lets say:

> > unit Data
> > interface
> > var
> >   MyList: TStringList;
> > ...
> > end;

> > unit Controler
> > interface
> >   procedure CreateList(aList: TStringList);
> > implementation
> >   procedure CreateList(aList: TStringList);
> >   begin
> >     aList := TStringList.Create;
> >   end;
> > ...
> > end.

> > unit Main;
> > ...
> >   Contoler.CreateList(Data.MyList);
> > ...
> > end.

> > This won't work (MyList will be kept to nil) if I don't declare the
aList
> > parameter as VAR aList.
> > What's the problem?
> > The aList object isn't pushed on the stack. A pointer is a pointer is a
> > pointer!
> > I can modify any VCL object passed in parameter without qualifying it as
a
> > pointer to a pointer (var).

> > It seems so a basic issue.... help...

> > Clement

Re:pointer vs. var parameter


"Clement Boucher" <clement.bouc...@chuq.qc.ca> skrev i en meddelelse
news:8ccob2$2mo4@bornews.borland.com...

Quote
> I use some kind of controler object to deconnect the creation of an
object.
> Lets say:

> unit Data
> interface
> var
>   MyList: TStringList;
> ...
> end;

> unit Controler
> interface
>   procedure CreateList(aList: TStringList);
> implementation
>   procedure CreateList(aList: TStringList);
>   begin
>     aList := TStringList.Create;
>   end;
> ...
> end.

> unit Main;
> ...
>   Contoler.CreateList(Data.MyList);
> ...
> end.

> This won't work (MyList will be kept to nil) if I don't declare the aList
> parameter as VAR aList.

Exactly.

Quote
> What's the problem?

There is no problem.
Just declare aList as var aList.
Then it will work just fine.

Finn Tolderlund

Re:pointer vs. var parameter


Quote
In article <8ccob2$2...@bornews.borland.com>, Clement Boucher wrote:
> The aList object isn't pushed on the stack. A pointer is a pointer is a
> pointer!

Agreed.

There are three methods of passing a StringLiat as a parameter:

  1) var list: TStringList
  2) const list: TStringList
  3) list: TStringList

All three methods place the same pointer onto the stack. The difference
relates to how this pointer can be changed.

 1) Not only can it be changed, but the changed value is passed back to
the caller.

 2) The value cannot be changed, but this does not stop you from modifying
its fields.

 3) The value can be changed by the called method, but the change is not
passed back to the caller.

 Mike Orriss (TeamB)
 (Unless stated otherwise, my replies relate to Delphi 4.03/5.00)
 (Unsolicited e-mail replies will most likely be ignored)

Re:pointer vs. var parameter


You are aware that StringList is a pointer itself, but when you declare it
as var aList: TStringList, you are actually providing a second level of
pointer.

If the variable myList is physically stored at address $12345678, and is
currently nil, when you call the procedure without the 'var', then the nil
will be pushed on the stack. In that instance, the compiler has no idea how
to place the new value into the variable myList, since the value $12345678
is not accessible to it. When you use the 'var', then instead of pushing nil
on the stack, it will push the value $12345678, which lets your creation
store the new value in the correct location.

Quote
"Clement Boucher" <clement.bouc...@chuq.qc.ca> wrote in message

news:8ccob2$2mo4@bornews.borland.com...
Quote
> Hi,
> (sorry for the english)

> As far I tought that I understood the way the pointers are handled in
> Delphi.
> I now face a problem with them. Help.

> I use some kind of controler object to deconnect the creation of an
object.
> Lets say:

> unit Data
> interface
> var
>   MyList: TStringList;
> ...
> end;

> unit Controler
> interface
>   procedure CreateList(aList: TStringList);
> implementation
>   procedure CreateList(aList: TStringList);
>   begin
>     aList := TStringList.Create;
>   end;
> ...
> end.

> unit Main;
> ...
>   Contoler.CreateList(Data.MyList);
> ...
> end.

> This won't work (MyList will be kept to nil) if I don't declare the aList
> parameter as VAR aList.
> What's the problem?
> The aList object isn't pushed on the stack. A pointer is a pointer is a
> pointer!
> I can modify any VCL object passed in parameter without qualifying it as a
> pointer to a pointer (var).

> It seems so a basic issue.... help...

> Clement

Re:pointer vs. var parameter


I don't know if this is true, but pretend that the pointer to the StringList is
pointing to some arbitrary memory location like 102 and so, the create function
gets 102 passed to it. Then you do the StringList.Create and it creates an
object and stores the pointer to the object at location 102. This is incorrect,
because you want the pointer to stored in MyList which may be sitting at
location 501.

sO, actually by not giving the VAR, you are not doing anything with the REAL
MyList. In fact it could give you a Memory Access Violation!

Davie

Quote
Clement Boucher wrote:
> Hi,
> (sorry for the english)

> As far I tought that I understood the way the pointers are handled in
> Delphi.
> I now face a problem with them. Help.

> I use some kind of controler object to deconnect the creation of an object.
> Lets say:

> unit Data
> interface
> var
>   MyList: TStringList;
> ...
> end;

> unit Controler
> interface
>   procedure CreateList(aList: TStringList);
> implementation
>   procedure CreateList(aList: TStringList);
>   begin
>     aList := TStringList.Create;
>   end;
> ...
> end.

> unit Main;
> ...
>   Contoler.CreateList(Data.MyList);
> ...
> end.

> This won't work (MyList will be kept to nil) if I don't declare the aList
> parameter as VAR aList.
> What's the problem?
> The aList object isn't pushed on the stack. A pointer is a pointer is a
> pointer!
> I can modify any VCL object passed in parameter without qualifying it as a
> pointer to a pointer (var).

> It seems so a basic issue.... help...

> Clement

Re:pointer vs. var parameter


Quote
In article <8cdmba$b...@bornews.borland.com>, James West wrote:
> You are aware that StringList is a pointer itself, but when you declare it
> as var aList: TStringList, you are actually providing a second level of
> pointer.

Not true, see my other post in this thread.

 Mike Orriss (TeamB)
 (Unless stated otherwise, my replies relate to Delphi 4.03/5.00)
 (Unsolicited e-mail replies will most likely be ignored)

Re:pointer vs. var parameter


Quote
In article <38EA6C73.3BD55...@smatters.com>, Davie wrote:
> sO, actually by not giving the VAR, you are not doing anything with the REAL
> MyList. In fact it could give you a Memory Access Violation!

Not true.

 Mike Orriss (TeamB)
 (Unless stated otherwise, my replies relate to Delphi 4.03/5.00)
 (Unsolicited e-mail replies will most likely be ignored)

Re:pointer vs. var parameter


Hi guys,

(sorry again for the english)

First of all, thank you very much for your help.
It seems that I'm not the only one having some trouble with this...but I
think I finally got the point.

To make a long story short, (with the help of Mike Orriss) everthing is
based on the way we're telling the compiler to handle the variable passed as
parameter.

Even if its a pointer, passing it by value doesn't allow us to modify its
"very nature" (its base address).
That is, we can deference the pointer to change the state or the properties
of the object but every changes made to the variable itself won't be pushed
back on the stack upon return.

Thats the job of the "pointer to a pointer" VAR qualifier.

Thanks again for your help.

Clment Boucher

P.S. As I work to improve my english, every comments will be appreciated.
Fell free to reply, specifiying where I made mistakes

Robert Marquardt <robert_marqua...@gmx.de> a crit dans le message :
38E9F353.2BF7...@gmx.de...

Quote
> TStringList is an object. An object is some memory.
> An object variable is a pointer which points to the object memory.
> you want to assign the object variable with some new object.
> Therefore you have to use var. var silently delivers the address
> (pointer to) of the variable. Usage of the var param name (assignment)
> silently dereferences this address/pointer.

> Clement Boucher schrieb:

> > Hi,
> > (sorry for the english)

> > As far I tought that I understood the way the pointers are handled in
> > Delphi.
> > I now face a problem with them. Help.

> > I use some kind of controler object to deconnect the creation of an
object.
> > Lets say:

> > unit Data
> > interface
> > var
> >   MyList: TStringList;
> > ...
> > end;

> > unit Controler
> > interface
> >   procedure CreateList(aList: TStringList);
> > implementation
> >   procedure CreateList(aList: TStringList);
> >   begin
> >     aList := TStringList.Create;
> >   end;
> > ...
> > end.

> > unit Main;
> > ...
> >   Contoler.CreateList(Data.MyList);
> > ...
> > end.

> > This won't work (MyList will be kept to nil) if I don't declare the
aList
> > parameter as VAR aList.
> > What's the problem?
> > The aList object isn't pushed on the stack. A pointer is a pointer is a
> > pointer!
> > I can modify any VCL object passed in parameter without qualifying it as
a
> > pointer to a pointer (var).

> > It seems so a basic issue.... help...

> > Clement

Re:pointer vs. var parameter


Quote
Mike Orriss (TeamB) wrote...
>In article <8cdmba$b...@bornews.borland.com>, James West wrote:
>> You are aware that StringList is a pointer itself, but when you declare it
>> as var aList: TStringList, you are actually providing a second level of
>> pointer.

>Not true, see my other post in this thread.

In fact, he's right. A pointer to the pointer is passed. You must have
misread what he says.
--
Rudy Velthuis

Re:pointer vs. var parameter


Quote
Clement Boucher wrote...
>Hi Robert,

>I'm aware that a object variable is a pointer to some memory used by/for the
>object type.
>There is however a point that I don't understand.  I can change one of the
>object property, by defenrencing
>the pointer passed as a parameter by value but I can't assign a new memory
>address to the same parameter.

You don't want to change the object the variable points to, you want to
change the variable itself.

Suppose you don't pass an object pointer, but a structure pointer.

  type
    PMyObj = ^TMyObj
    TMyObj = record
      First: Integer;
      ...
    end;

  procedure ChangeObj(Obj: PMyObj);
  begin
    Obj^.First := 11; // you change the object
  end;

  var
    ObjPtr: PMyObj;

  procedure AssignObj(var Obj: PMyObj);
  begin
    New(Obj); // you change the object pointer.
  end;

  ...

  AssignObj(ObjPtr);

ChangeObj only changes the record. AssignObj however changes the pointer
itself, so the pointer must be passed by reference, not by value. You
pass the address of the pointer, not the address the pointer points to
(the contents of the pointer).

The same goes for object pointers. You want to change the value of the
variable, not of the object it refers to. Object variables are by default
pointers.  
--
Rudy Velthuis

Re:pointer vs. var parameter


Quote
Davie wrote...
>sO, actually by not giving the VAR, you are not doing anything with the REAL
>MyList. In fact it could give you a Memory Access Violation!

That just means that the newly created StringList is assigned to the
parameter (parameters can be seen as local variables). So the reference
is lost as soon as the procedure ends.
--
Rudy Velthuis

Re:pointer vs. var parameter


Quote
"Mike Orriss (TeamB)" wrote:

> There are three methods of passing a StringLiat as a parameter:

>   1) var list: TStringList
>   2) const list: TStringList
>   3) list: TStringList

make it four:
    4) out list: TStringList

I've seen this used in Borland code. I think in this case, the value
must be changed ?

Re:pointer vs. var parameter


Hmmm, I did a test with passing the StringList with NO Var and in the function I
called, I do the create and add a few lines. Then after returning from the
function that has the header incorrectly defined, the next line in my main logic
tells it to display item 0 from the list and I get a memory access violation. I
would expect that , but you don't think so, why is that?

Davie

Quote
"Mike Orriss (TeamB)" wrote:
> In article <38EA6C73.3BD55...@smatters.com>, Davie wrote:
> > sO, actually by not giving the VAR, you are not doing anything with the REAL
> > MyList. In fact it could give you a Memory Access Violation!

> Not true.

>  Mike Orriss (TeamB)
>  (Unless stated otherwise, my replies relate to Delphi 4.03/5.00)
>  (Unsolicited e-mail replies will most likely be ignored)

Go to page: [1] [2]

Other Threads