Sign in Join

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

Mailing lists / fpc-pascal / 2010-05

stuck with untyped pointer

17 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

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

spir ☣

Hello,

While waiting for more information about how to use "associated objects" with TStringList, I started to implement // lists for names (TString) and values (TFPList). This builds a kind of flexible record type, I called "Struct" because the name "Record" is not available ;-) Values are in in fact Struct-s themselves. All works fine when storing data, but I cannot get it back. Precisely,

   i := self.names.indexOf(name);
   val := Struct(self.values[i]);

raises "got untyped expected Struct". Sure, that's why I'm trying to cast... Without casting to Struct, the compiler indeed throws "got pointer expected Struct". I'm very surprised since I already did this.

So, I quickly wrote a simpler test case wrapping structure, just putting objects in a TFPList and casting back: all works fine:

========================
program __essai__;
{$mode objfpc}{$H+}
uses
    Classes, SysUtils;
type Struct    = Class
        val    : Integer;
        constructor struct(i:Integer);
        function text : String;
    end;
constructor Struct.struct(i:Integer);
begin
    inherited;
    self.val := i;
end;
function Struct.text : String;
begin
    result := '<' +intToStr(self.val)+ '>';
end;
var
    s    : Struct;
    l    : TFPList;
begin
    s := Struct.struct(1);
    writeln(s.text);
    l := TFPList.create;
    l.add(s);
    s := Struct(l[0]);    //////////////////
    writeln(s.text);
end.
=== output ===
<1>
<1>

Thank you,

Denis
________________________________

vit esse estrany ☣

spir.wikidot.com

Reply by email

Michael Van Canneyt
to spir ☣
spir ☣ wrote 9 lines
Hello, While waiting for more information about how to use "associated objects" with TStringList, I started to implement // lists for names (TString) and values (TFPList). This builds a kind of flexible record type, I called "Struct" because the name "Record" is not available ;-) Values are in in fact Struct-s themselves. All works fine when storing data, but I cannot get it back. Precisely, i := self.names.indexOf(name); val := Struct(self.values[i]); raises "got untyped expected Struct". Sure, that's why I'm trying to cast... Without casting to Struct, the compiler indeed throws "got pointer expected Struct". I'm very surprised since I already did this. So, I quickly wrote a simpler test case wrapping structure, just putting objects in a TFPList and casting back: all works fine:

If you want this, I suggest you does all this for you. It has an extensive testsuite, so plenty of code to peep at.

Michael.

Show quoted text 52 lines
======================== program __essai__; {$mode objfpc}{$H+} uses Classes, SysUtils; type Struct = Class val : Integer; constructor struct(i:Integer); function text : String; end; constructor Struct.struct(i:Integer); begin inherited; self.val := i; end; function Struct.text : String; begin result := '<' +intToStr(self.val)+ '>'; end; var s : Struct; l : TFPList; begin s := Struct.struct(1); writeln(s.text); l := TFPList.create; l.add(s); s := Struct(l[0]); ////////////////// writeln(s.text); end. === output === <1> <1> Thank you, Denis ________________________________ vit esse estrany ☣ spir.wikidot.com _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply by email

Alberto Narduzzi
to spir ☣: While waiting for more information about how to use "associated objects" with…
i := self.names.indexOf(name); val := Struct(self.values[i]); raises "got untyped expected Struct". Sure, that's why I'm trying to cast... Without casting to Struct, the compiler indeed throws "got pointer expected Struct". I'm very surprised since I already did this.

in first place, you can omit self within the object's methods, as it's implicitly there.

second, the property Values[] expects a string inside "[]" and not a
number, so you may want to use val := Values[name];

third, Values return a string (the rightmost part of the "=" if you read the items property (or directly l[n])), so you cannot cast it to "Struct".

I think you intend to do something like:

Var
MyStruct: Struct;
MyList: TStringList;
I: Integer;

(...)

MyList := TStringList.Create();

(...)

For I := 0 To 10 Do
Begin
   MyStruct := Struct.struct(I);
   MyList.AddObject(Format('struct no. %d', [I]), TObject(MyStruct));
End;

{cannot remember whether the casting to TObject is necessary or not, or any syntax error I might have done, because I'm typing it out of my mind, after a year or so I haven't written any pascal code... anyway, I suggest you derive your Struct from TObject. And for a matter of readability, I also suggest you name it TStruct instead of plainly Struct, but this is a matter of taste}

(...)

you can now retrieve the objects you added with:

For I := 0 To Pred(MyList.ItemsCount) Do
Begin
   MyStruct := Struct(MyList.Objects[I]);
   ...do whatever you like with your struct variable here...
End;

If you need to retrieve your objects using the "names" you need to do something like:

I := MyList.IndexOfName("struct no. 6");
If(I >= 0)
   MyStruct := Struct(MyList.Objects[I]);

or more rapidly, if you are sure the "name" exists, with

MyStruct := Struct(MyList.Objects[MyList.IndexOfName("struct no. 6")]);

bear in mind that free-ing MyList does not free the instances of Struct you have created and inserted; so you need to do it manually, in another for-cycle, for example...

For I := 0 To Pred(MyList.ItemsCount) Do
Begin
   MyStruct := Struct(MyList.Objects[I]);
   MyStruct.Free;
End;

If you intended to retrieve your objects directly with Names[] and Values[] then forget it. Unless you descend from TStrings and write the property accordingly (and all the other virtual methods, of course)

Or you can descend from TStringList (don't know if this is the best thing you could do, but...), and add a property ObjectValues, with a proper Getter and Setter expecting a string instead of an integer; like:

property ObjectValues[const AName:String]: TObject Read GetObjectValue
write SetObjectValue;
Function TMyStringList.GetObjectValue(const AName:String):TObject;
Var I:Integer;
Begin
   Result := Nil;
   I := IndexOfName(AName);
   If (I >= 0) Then
     Result := Objects[I];
End;
Procedure TMyStringList.SetObjectValue(const AName:String; AObject:TObject);
Var I:Integer;
Begin
   I := IndexOfName(AName);
   If (I >= 0) Then
     Objects[I] := AObject;
End;

As I said, take all this with a grain of salt, as I may have written mistakes and/or forgot something.

Just my 2c, hope this helps.

Cheers, A.

Reply by email

spir ☣
to Alberto Narduzzi
Show quoted text 6 lines
> i := self.names.indexOf(name); > val := Struct(self.values[i]); > raises "got untyped expected Struct". Sure, that's why I'm trying to cast... Without casting to Struct, the compiler indeed throws "got pointer expected Struct". I'm very surprised since I already did this. in first place, you can omit self within the object's methods, as it's implicitly there.

Right. Just personal preference for expliciteness. (Even if I don't like magic names.)

second, the property Values[] expects a string inside "[]" and not a number, so you may want to use val := Values[name];

No. Sorry, I was not clear enough. Self here is a Struct, and Struct is custom class type. Its .values attribute is a TFPList holding objects, which also happen to be Struct-s; but they could be any kind of pointed thingies. .names is a TStringList. (*) My issue is I cannot cast a value (thus a struct) back to its Struct type. The compiler refuses. But I can do exactly the same operation, for any reason, with the simpler case appended to the previous post.

third, Values return a string (the rightmost part of the "=" if you read the items property (or directly l[n])), so you cannot cast it to "Struct".

... see above, and the example. It *is* a Struct.

Show quoted text 27 lines
I think you intend to do something like: Var MyStruct: Struct; MyList: TStringList; I: Integer; (...) MyList := TStringList.Create(); (...) For I := 0 To 10 Do Begin MyStruct := Struct.struct(I); MyList.AddObject(Format('struct no. %d', [I]), TObject(MyStruct)); End; {cannot remember whether the casting to TObject is necessary or not, or any syntax error I might have done, because I'm typing it out of my mind, after a year or so I haven't written any pascal code... anyway, I suggest you derive your Struct from TObject. And for a matter of readability, I also suggest you name it TStruct instead of plainly Struct, but this is a matter of taste} (...)

Yes, thank you for this example. I will probably do this later. But as of now, since I did not now TStringList implements the "associated object" features, I use a // TFPList of objects; instead of a TStringList's .Object attribute. hope it's clear. It's exactly the same scheme, in fact, and I doubt there is any loss & again at using the one or the other.

Show quoted text 5 lines
you can now retrieve the objects you added with: For I := 0 To Pred(MyList.ItemsCount) Do Begin MyStruct := Struct(MyList.Objects[I]);
This is precisely what the compiler refuses in my case. To be fully explicite, the above translates in my case (since both container and the values are structs):
    MyStructValue := Struct.(StructContainer.values[I]);
Show quoted text 9 lines
...do whatever you like with your struct variable here... End; If you need to retrieve your objects using the "names" you need to do something like: I := MyList.IndexOfName("struct no. 6"); If(I >= 0) MyStruct := Struct(MyList.Objects[I]);

Yes, this is the code you commented on top of this post:

Show quoted text 12 lines
> i := self.names.indexOf(name); > val := Struct(self.values[i]); bear in mind that free-ing MyList does not free the instances of Struct you have created and inserted; so you need to do it manually, in another for-cycle, for example... For I := 0 To Pred(MyList.ItemsCount) Do Begin MyStruct := Struct(MyList.Objects[I]); MyStruct.Free; End;

Yes, thank you for this warning. And, believe it or not, this is precisely in the destructor that the compiler refuses my casting. The reason there is no test. The whole .free methoid reads (untested since the compiler blocks):

destructor Struct.free;
{ Free values before freeing the structure itself. }
var i        : Integer;
    val      : Struct;
begin
    self.names.destroy;
    for i:=0 to self.count-1 do begin
        val := Struct(self.values[i]);
        val.free;
        val := nil;
    end;
    self.values.destroy;
    inherited;		// useless???
end;
Or you can descend from TStringList (don't know if this is the best thing you could do, but...), and add a property ObjectValues, with a proper Getter and Setter expecting a string instead of an integer; like:

No, this does not match my case. I'd rather have a linked list for names since it is only traversed, to find the index of a value (so the method could follow pointers, instead of computing them like for an array). But I keep the code below, thank you, as an example or property implementation (haven't written any yet).

Show quoted text 25 lines
property ObjectValues[const AName:String]: TObject Read GetObjectValue write SetObjectValue; Function TMyStringList.GetObjectValue(const AName:String):TObject; Var I:Integer; Begin Result := Nil; I := IndexOfName(AName); If (I >= 0) Then Result := Objects[I]; End; Procedure TMyStringList.SetObjectValue(const AName:String; AObject:TObject); Var I:Integer; Begin I := IndexOfName(AName); If (I >= 0) Then Objects[I] := AObject; End; As I said, take all this with a grain of salt, as I may have written mistakes and/or forgot something. Just my 2c, hope this helps.

Thank you very much.

Denis

(*) Struct is in fact the root type of an OO type system. It should be called "Unit" but for any reason the compiler also refuses this name ;-) The OO framework is to be written "in itself", meaning the model only uses its own features to define itself. There is a name for this kind of reflexivity. It is the reason why the content of a Struct is structs. Looks like a joke... Later, even the names will be (instances of a subtype of) Struct. I don't know where this path leads (PascaLisp?), but I'm sure I want to follow it :-) ________________________________

vit esse estrany ☣

spir.wikidot.com

Reply by email

spir ☣
to Alberto Narduzzi: in first place, you can omit self within the object's methods, as it's implicitly there.…

Hello,

It was a stupid naming issue: since I couldn't use "new", I had called the Struct constructor "struct" (found it logical, since it returns a struct). But because of case insensibility, I guess, when I wanted to cast back a pointer to Struct, the compiler denoted the constructor instead -- I guess. Anyway, changed Struct.struct to Struct.clone and all runs fine.

The kind of bug that could render crazy :-)
Thank you for your help.

Denis
________________________________

vit esse estrany ☣

spir.wikidot.com

Reply by email

José Mejuto
to spir ☣: While waiting for more information about how to use "associated objects" with…

Hello FPC-Pascal,

Friday, May 28, 2010, 6:57:42 PM, you wrote:

s> ========================
s> program __essai__;
s> {$mode objfpc}{$H+}
s> uses
s> Classes, SysUtils;

s> type Struct    = Class
s>         val    : Integer;
s>         constructor struct(i:Integer);
s>         function text : String;
s>     end;

Apart the memory leaks wich are quite sure on purpose, you are using a loudspeaker calling for problems in the future:

1) Constructor with the same name as class name. If you write in code:

procedure Struct.DoSomething;
var
  n: Struct;
begin
  n:=Struct(0);
end;

Which should the compiler do ? Create a new object n calling the Struct constructor using 0 as parameter, or cast zero to n ?

2) 2 constructors, one works the other simply does nothing. You can not "hide" the constructor "Create" as you are inheriting from TObject.
3) Variable name "val" (Use Value instead, there is a function called val).

Best regards, José

Reply by email

Alberto Narduzzi
to spir ☣: On Fri, 28 May 2010 20:51:10 +0300 Right. Just personal preference for expliciteness.…

ok, now the code fragments look more clear.

I have no more suggestions but the one about deriving your TStruct from TObject, as almost everything in the LCL (and/or VCL, I guess I name them right) is a descendant of it.
Again. maybe it's not the best thing you'll like to do, but this way IMHO you'll save yourself a lot of frustration ;-)

Cheers, A.

Reply by email

José Mejuto
to Alberto Narduzzi

Hello FPC-Pascal,

Friday, May 28, 2010, 11:24:44 PM, you wrote:

AN> I have no more suggestions but the one about deriving your TStruct from AN> TObject, as almost everything in the LCL (and/or VCL, I guess I name AN> them right) is a descendant of it.

Struct is declared as "class" so it inherits from TObject if not other class is especified.

If Struct was declared as "Object" that would be another story.

Best regards, José

Reply by email

spir ☣
to José Mejuto: s> ======================== s> program __essai__; s> {$mode objfpc}{$H+} s> uses s> …
3) Variable name "val" (Use Value instead, there is a function called val).

Naming problems in object pascal... I could not use "value" because it's the name of a method that returns a value, lol! So, I used "val". But now I cannot use "val". Will end up with "v". Should we only use single-letter var names to be sure? Pascal is already problematic with names because of (1) many keywords (2) loads of builtin funcs and procs (3) case-insensitivity. But the object layer brings the biggest issue with the implicit "self" causing names external to a method to clash with local names. Like if there were no local , the names one would need to use, because they make sense for a given class, are precisely the ones that clash with data or method attributes. Worse: the compiler _sometimes_ blocks when var names conflict with slot names (I have not yet understood when/why it does or not). No offense intended, but I consider this as a language-design error. (symptom: lexical paralysis ; cause: namespace leak)

Denis

PS: Tricks to work around these problems welcome :-) How do you solve that? (One I won't use because I find it ugly is ___prefixing or postfixing___ all var names, or ___both___.) ________________________________

vit esse estrany ☣

spir.wikidot.com

Reply by email

Alberto Narduzzi
to José Mejuto: AN> I have no more suggestions but the one about deriving your TStruct from AN> TObject,…

Hi,

Struct is declared as "class" so it inherits from TObject if not other class is especified.

is that true? I don't mean not to trust you, but is the compiler assuming that, or is it a FPC rule? IMO a class is a class, and doesn't inherit from anything else. Unless specified. BTW, From who does TObject inherit then?
Just asking, I never declare anything as a pure class, or if I do I don't care if it descends from TObject or not, actually...

If Struct was declared as "Object" that would be another story.

no doubt on this.

Cheers, A.

Reply by email

José Mejuto
to Alberto Narduzzi

Hello FPC-Pascal,

you wrote
> Struct is declared as "class" so it inherits from TObject if not other > class is especified.

AN> is that true? I don't mean not to trust you, but is the compiler AN> assuming that, or is it a FPC rule? IMO a class is a class, and doesn't AN> inherit from anything else. Unless specified. BTW, From who does TObject AN> inherit then?

TObject is the base class, it inherits from nobody. To make the whole weel run a base class must exists which provide basic functionality like Create/Destroy and other methods/events like "ClassName", "InheritsFrom"; so if no class is specified it automatically inherits from TObject.

AN> Just asking, I never declare anything as a pure class, or if I do I AN> don't care if it descends from TObject or not, actually...

Pure class in the same idea does not exists in Pascal as in C, or at least they do not exists a few time ago.

Best regards, José

Reply by email

José Mejuto
to spir ☣: On Fri, 28 May 2010 23:07:35 +0200 Naming problems in object pascal... I could not use…

Hello FPC-Pascal,

you wrote
> 3) Variable name "val" (Use Value instead, there is a function called > val).

s> Naming problems in object pascal... I could not use "value" s> because it's the name of a method that returns a value, lol! So, I s> used "val". But now I cannot use "val". Will end up with "v".

You can use "val" as you can use "struct" as a constructor, but you lost some precision about the intention of the code. When you code in Pascal you should (not must) follow the background idea, like using Create as constructor as you are inheriting from TObject. If a function returns a "Value" usually this method is called "GetValue", Pascal have properties so you do not need to fake functions as they where variables (usual in C code).

s> Should we only use single-letter var names to be sure?

The only one convention that most people uses is to prefix with F all variables to be accesed by properties, well, and call the events "Onxxxx".

s> Pascal is already problematic with names because of (1) many s> keywords

Hmmm... Pascal only have around 30-35 keywords, am I wrong ?

s> (2) loads of builtin funcs and procs

Hmmm... well, yes.

s> (3) case-insensitivity.

At least for me this is not a problem at all, at least it avoids things like:

A=HWND((A==NULL) ? hwnd : hWND;

(its real code, except the "A" which I do not recall the real name).

s> But the object layer brings the biggest issue with the implicit s> "self" causing names external to a method to clash with local s> names.

Hmmm... I think that this should not happend. Is the case in your posted example ?

s> Worse: the compiler _sometimes_ blocks when var names conflict with s> slot names (I have not yet understood when/why it does or not). s> No offense intended, but I consider this as a language-design s> error. (symptom: lexical paralysis ; cause: namespace leak)

Var names "slot" names ? Which is a "slot name" ? Can you post a brief example ?

Best regards, José

Reply by email

Alberto Narduzzi
to José Mejuto: AN> is that true? I don't mean not to trust you, but is the compiler AN> assuming that,…
Show quoted text 5 lines
TObject is the base class, it inherits from nobody. To make the whole weel run a base class must exists which provide basic functionality like Create/Destroy and other methods/events like "ClassName", "InheritsFrom"; so if no class is specified it automatically inherits from TObject.

I see, and I suspected it was for these reasons, but allow me to say this is some sort of helper functions one might not need. "InhritsFrom", just like Delphi's "Is" (don't know if FPC has the same keyword, anyway) are things that can be dealt with the RTTI...

Pure class in the same idea does not exists in Pascal as in C, or at least they do not exists a few time ago.

classes in C are just mere structures, with no inheritance capability (i.e no VMT, AFAIK). I'm talking about C99, not C with classes and-or-the-like-extensions to the language.
In C++ no base class exists. I can define a "class TMyClass" descending from nothing, and have nothing else than it, as my _base_ class. Not talking about "visual" C/C++ compliers here (which can indeed hide something to ease the RTTI engine help the programmer, somehow), just pure GCC.
If I am wrong, please correct me, as this is what I have always had the idea it worked (and _should_ work, FWIW...)

Cheers, A.

P.S.
I'll probably read/reply tomorrow (ok, later today, GMT + 3...), as now I'm tired and wishing to go to bed ;-)

Reply by email

José Mejuto
to Alberto Narduzzi

Hello FPC-Pascal,

you wrote 5 lines
> TObject is the base class, it inherits from nobody. To make the whole > weel run a base class must exists which provide basic functionality > like Create/Destroy and other methods/events like "ClassName", > "InheritsFrom"; so if no class is specified it automatically inherits > from TObject.

AN> I see, and I suspected it was for these reasons, but allow me to say AN> this is some sort of helper functions one might not need. AN> "InhritsFrom", just like Delphi's "Is" (don't know if FPC has the same AN> keyword, anyway) are things that can be dealt with the RTTI...

The classes in Pascal are more like "MFC" framework in MSVC. Most functions does not eat a single byte of memory, RTTI are much more memory expensive (maybe somebody corrects me?).

> Pure class in the same idea does not exists in Pascal as in C, or at > least they do not exists a few time ago.

AN> classes in C are just mere structures, with no inheritance capability AN> (i.e no VMT, AFAIK). I'm talking about C99, not C with classes AN> and-or-the-like-extensions to the language.
AN> In C++ no base class exists. I can define a "class TMyClass" descending AN> from nothing, and have nothing else than it, as my _base_ class.

In Pascal that's a "Object" not a "Class". There was a recent thread about the differences and why Classes are more used than objects.

AN> P.S.
AN> I'll probably read/reply tomorrow (ok, later today, GMT + 3...), as now AN> I'm tired and wishing to go to bed ;-)

Have nice dreams...

Best regards, José

Reply by email

spir ☣
to José Mejuto: s> Naming problems in object pascal... I could not use "value" s> because it's the name…
Show quoted text 6 lines
s> But the object layer brings the biggest issue with the implicit s> "self" causing names external to a method to clash with local s> names. Hmmm... I think that this should not happend. Is the case in your posted example ?

I mean when (how do you call this in Pascal: attributes?), say, fields and/or method names conflict with simple (usually local) variable names. This only happens because fields/methods can be denoted implicitely. So, the compiler may relate a name "value" to a "value" slot of the class of the current target; while the for the programmer "value" is a local var. And the value slot has nothing to do here -- but the compiler cannot know it. I find this wrong. Well, just my point of view. This design choice causes namespaces to leak ;-) In any other case, a locally introduced name acts like if were prefixed eg "local.value": private to the current namespace and thus totally safe. Object pascal's design choice makes field/method names also belong to every local namespace!

Show quoted text 7 lines
s> Worse: the compiler _sometimes_ blocks when var names conflict with s> slot names (I have not yet understood when/why it does or not). s> No offense intended, but I consider this as a language-design s> error. (symptom: lexical paralysis ; cause: namespace leak) Var names "slot" names ? Which is a "slot name" ? Can you post a brief example ?

Sorry, I'm using terminology imported form another paradigm: "slot" is a general word for either data (property) or executable (method) field of a given object. Rather used in the prototype-based community. (A very practicle word because unambiguous; even "attribute" is sometimes unclear, may denote only data slots for some people, or only public ones. Slot only and always means "any kind of element belonging to an object".)

Denis
________________________________

vit esse estrany ☣

spir.wikidot.com

Reply by email

spir ☣
to Alberto Narduzzi: is that true? I don't mean not to trust you, but is the compiler assuming that, or is it…
Show quoted text 11 lines
Hi, > Struct is declared as "class" so it inherits from TObject if not other > class is especified. is that true? I don't mean not to trust you, but is the compiler assuming that, or is it a FPC rule? IMO a class is a class, and doesn't inherit from anything else. Unless specified. BTW, From who does TObject inherit then? Just asking, I never declare anything as a pure class, or if I do I don't care if it descends from TObject or not, actually...

Hum, there must be a root type, from which all others inherit primitive object mechanics. Such as, and mainly, accessing an attribute. Now, this needs not be obvious on the user-language side, but generally it is. So a test such as anything.isOfType(RootObject) always returns true. Don't know about free pascal, but this is very probable (and I assumed it's true before the question was raised).

I take the opportunity to ask about inherited attribute (only methods in FP?) transmission and lookup: there are 2 common schemes:
* Copy: A subclass holds copies of (references to) inherited methods. So, lookup stops on an object's class.
* Delegation: A subclass delegates to its superclass when a looked up attribute is not found locally. (The superclass may itself delegate further, this up to the root class.)

Maybe this does not apply to, or is irrelevant in, a static language. I imagine the compiler can directly bind a reference to eg anObject.aMethod wherever aMethod may be defined; since it knows the whole hierarchy. So, this may have no 'd like to have more accurate information on this topic, because if it has any importance I will try to flatten as much as possible my object system; else I can "free-mindly" build vertical hierarchies, which often better mirror the semantics.

Thank you all,
denis
________________________________

vit esse estrany ☣

spir.wikidot.com

Reply by email

Michael Van Canneyt
to spir ☣
spir ☣ wrote 17 lines
On Sat, 29 May 2010 01:09:50 +0300 Alberto Narduzzi wrote: > Hi, > >> Struct is declared as "class" so it inherits from TObject if not other >> class is especified. > > is that true? I don't mean not to trust you, but is the compiler > assuming that, or is it a FPC rule? IMO a class is a class, and doesn't > inherit from anything else. Unless specified. BTW, From who does TObject > inherit then? > Just asking, I never declare anything as a pure class, or if I do I > don't care if it descends from TObject or not, actually... Hum, there must be a root type, from which all others inherit primitive object mechanics. Such as, and mainly, accessing an attribute. Now, this needs not be obvious on the user-language side, but generally it is. So a test such as anything.isOfType(RootObject) always returns true. Don't know about free pascal, but this is very probable (and I assumed it's true before the question was raised).

All classes descent from TObject, always: implicitly or explicitly.

I take the opportunity to ask about inherited attribute (only methods in FP?) transmission and lookup: there are 2 common schemes: * Copy: A subclass holds copies of (references to) inherited methods. So, lookup stops on an object's class. * Delegation: A subclass delegates to its superclass when a looked up attribute is not found locally. (The superclass may itself delegate further, this up to the root class.)

Static methods are directly bound by the compiler. For virtual methods: the actual pointer to the method is in the VMT A pointer to the VMT is initialized when an instance is created. But I am not sure whether VMTs are linked or whether they are copied for descendents.

Michael.

Reply by email