Sign in Join

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

Mailing lists / fpc-pascal / 2002-10

self

8 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

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

Adam Naumowicz

Hello,
My friend noticed recently, that with version 1.1 you cannot write something like that:

type t = object
procedure p(s:t);
end;
procedure t.p(s:t);
begin
self:=s;
end;

It causes 'Illegal expression' where self is assigned. Does it mean that with the new version self is read only ? I hope not.

Best regards,
Adam Naumowicz

====================================================================== Department of Applied Logic fax. +48 (85) 745-7662 Institute of Computer Science tel. +48 (85) 745-7559 (office) University of Bialystok e-mail:
Sosnowa 64, 15-887 Bialystok, Poland http://math.uwb.edu.pl/~adamn/ ======================================================================

Reply by email

Unknown author

Hello,

Show quoted text 7 lines
type t = object procedure p(s:t); end; procedure t.p(s:t); begin self:=s; end;

Shouldn't 'procedure p(s:t);' actually have a pointer to 't' rather than a stack allocated 't'?

This is extremely bad coding imho. You are basically throwing away 'self' and creating a memory leak. It's a good thing (tm) if the compiler *is* telling you that it's illegal, even better if it is an error.

consider this:

 type
   t = class  //altered from object so I don't have to remember the syntax
     procedure p(s:t);
   end;
   procedure t.p(s:t);
   begin
     self:=s;
   end;
   ...
   var
     a, b: T;
   begin
     a := T.create;
     b := T.Create;
     a.p(b);
     //Q: what does 'a' now point to? A: 'b'.
     //Q: where does the memory referenced by 'a' point to?
     //A: nothing. This causes a memory leak.
   end;
   ...
It causes 'Illegal expression' where self is assigned. Does it mean that with the new version self is read only ?

Self should be read-only. Every instance has it's own 'self' and it makes no sense to alter what is points to.

What are you trying to achieve by re-assigning the value of 'self' anyway?

---------------------------------------------
This message was sent using Mistral WebMail.
http://www.mistral.co.uk/

Reply by email

Jonas Maebe
to Unknown author
Show quoted text 11 lines
> type t = object > procedure p(s:t); > end; > procedure t.p(s:t); > begin > self:=s; > end; Shouldn't 'procedure p(s:t);' actually have a pointer to 't' rather than a stack allocated 't'?

Because he's working with objects and wants to replace the contents of the current object with another one: no (it could be designated "const" for better performance maybe). Remember, in an object (as opposed to a class instance), self is not a pointer but the object itself. So he's just overwriting the contents of the object with some other contents. I agree it's ugly, but it won't create a memory leak.

Jonas

Reply by email

Ingmar Tulva
to Jonas Maebe

One thing is unclear to me:

type
  t1 = object
    procedure p(var s:t1);
  end;
  t2 = object(t1)
    {some fields here}
  end;
procedure t1.p (var s:t1); { or "const" or ^t1 }
 begin
   Self:=s;
 end;
var
  o1,o2 : t2;
begin
  ---
  o1.p(o2);
  ---
end.

Will the additional fields of t2 be assigned or not? If not, then what is the use of this feature (assigning something to Self)? Otherwise, what if the declarations were:

var o1:t1; o2:t2;

or:

var o1:t2; o2:t1;

Not only ugly but confusing :-)

------

Ingmar Tulva

Reply by email

Jonas Maebe
to Ingmar Tulva
Ingmar Tulva wrote 24 lines
type t1 = object procedure p(var s:t1); end; t2 = object(t1) {some fields here} end; procedure t1.p (var s:t1); { or "const" or ^t1 } begin Self:=s; end; var o1,o2 : t2; begin --- o1.p(o2); --- end. Will the additional fields of t2 be assigned or not?

I don't think the above will even compile, because var parameters must match exactly. Anyway, the extra fields cannot be assigned, because they don't exist in t1 (so there is no memory available to put them in).

If not, then what is the use of this feature (assigning something to Self)?

You can replace the values of all the fields of an object with those of another object inside a method (this is important, because when you're outside a method, you can simply assign one object to another) without having to type all the fields explicitely.

Jonas

Reply by email

Ingmar Tulva
to Jonas Maebe

On Wed, 23 Oct 2002, Jonas Maebe wrote:

}I don't think the above will even compile, because var parameters must }match exactly.

Huh? Not in case of objects! The type of the actual parameter must be the same as or descendant of the type of the formal parameter, as I recall. Just like with pointers to objects. And if I'm right, then..

}You can replace the values of all the fields of an object with those of }another object inside a method (this is important, because when you're }outside a method, you can simply assign one object to another) without }having to type all the fields explicitely.

...you cannot replace them all, because the program flow can fall on t1.p() without any clue about what new kinds of descendants of t1 could be Self or the actual parameter. When dealing with objects or classes, you never really know it. So it seems, all that can be done is to assign the fields declared in t1.
Then again, if t1.p() cannot handle additional fields of decendants, then all its descendants inherit a method which can, for some reason, replace a part of the object with corresponding part of another object?

Well, it's very much a matter of aesthetics. Maybe it's just me but I feel that if Self:=Something were allowed, it should properly handle all possible descendant types of both Self and Something - but that is impossible to accomplish.

One more example:

type
  t1 = object
    procedure p ({var/const/whatever} s:t1);
  end;
  t2 = object(t1);
  end;
  t3 = object(t1)
  end;
procedure t1.p (s:t1);
 begin
   Self:=s;
 end;
var
  o1 : t1;
  o2 : t2;
  o3 : t3;
begin
  ---
  o2.p(o3);
  ---
end.

What type o2 now belongs to? If Self:=... is equivalent to assignment of records, then VMT pointer was assigned, too, and o2 has VMT of type t3 (which leads to question, what happens when o1:=o3? Honest, I don't know). Or, if you have taken care of this and don't assign VMT pointer together with fields, imagine that t1 containes a field which is to be interpreted differently by t2 and t3 - like, for example, TCluster.Value of Turbo Vision? Also, note that we couldn't do o2:=o3 in the above example - compiler would give type mismatch, and for good, I think.

Just to keep discussion alive,
Ingmar Tulva

Reply by email

Adam Naumowicz
to Jonas Maebe: I don't think the above will even compile, because var parameters must match exactly.…
Jonas Maebe wrote 11 lines
I don't think the above will even compile, because var parameters must match exactly. Anyway, the extra fields cannot be assigned, because they don't exist in t1 (so there is no memory available to put them in). > If not, then what is > the use of this feature (assigning something to Self)? You can replace the values of all the fields of an object with those of another object inside a method (this is important, because when you're outside a method, you can simply assign one object to another) without having to type all the fields explicitely.

Exactly, it's useful when you want to copy a whole object at a time + VMT. As it used to be a 100% valid Pascal expression for some twenty years, my original question was why it was forbiden in FPC 1.1. Can it be restored (for the sake of Borland compatibility for instance) ?

Adam Naumowicz

====================================================================== Department of Applied Logic fax. +48 (85) 745-7662 Institute of Computer Science tel. +48 (85) 745-7559 (office) University of Bialystok e-mail:
Sosnowa 64, 15-887 Bialystok, Poland http://math.uwb.edu.pl/~adamn/ ======================================================================

Reply by email

Ingmar Tulva
to Adam Naumowicz

On Wed, 23 Oct 2002, Adam Naumowicz wrote:

}Exactly, it's useful when you want to copy a whole object at a time + VMT. }As it used to be a 100% valid Pascal expression for some twenty years, my }original question was why it was forbiden in FPC 1.1. Can it be restored }(for the sake of Borland compatibility for instance) ?

So it really copies VMT pointer? Creepy :-) But well, I agree, if it is allowed in TP and even useful, it would probably be better to allow it in FPC, too.

Ingmar Tulva

Reply by email