According to Pierre Phaneuf:
That's the problem (that you're not sure it will not change). BTW, the constructor *is* the logical place do to such a thing...
I agree, but not every constructor call does actually initialize an object. Since it is difficult to be sure whether an object already is initialized or not, we have to decide about this when the constructor is *called*. For this reason, it happened to be easier to do the initialization outside the constructor's body.
If we find a method to be *sure* if the object is initialized, I can change constructors to do initialization in the body. Anyway, this does not matter unless you do tricks like `GetMem'ming an object.
But how do you check if an object is initialized or not?
Look whether the VMT field contains a nonzero value. To be absolutely sure, we can even check whether the pointer really points to a VMT: The first Word pointed to must be a positive Integer (the size of the object), the second one its negative (which is included for purposes like this one). Problem: This will only work if the object was pre-initialized to have a zero VMT field. This can be achieved with `New', but not with `GetMem', so you have still to be careful when implementing streams.
I don't think this is the best way either, unless you can devise a *sure* way to check out if the object is initialized.
What else would you propose?
In BP it cannot. It *must* be a constructor, because this is relied upon by TStream.Get to initialize the object VMT link correctly and allocate the correct amount of memory.
It could be in BP too, if we changed the `tStream' object. Just do everything, the constructor would normally do, by hand.
I am doing a BP compatible StreamRec facility for the BPCOMPAT package.
Great! }:-=)= (* This shall be a smiling Gnu. :*)
Are we looking for BP compatibility or not?
We are in part. The primary goal of GPC is to produce the best Pascal compiler the world has ever seen. (See the Info documentation for details.) BP compatibility is desireable because (ii) BP is not too bad and (i) many BP programmers will try GPC only if they can use their existing programs without any change.
BTW, I *am* also developing a class library made just for GPC using all the new features and fixing many of the problems with the BP OBJECTS.PAS and the TurboVision libraries.
:-)
It would be nice to have RTL functions to get an object name and parent, a bit like Delphi can give you the class name of an object.
How does Delphi do this? (Sorry for the stupid question, but my experience with Delphi is very limited, primarily because I cannot stand the mouse-only "user interface".)
A separate function would be better (probably something accepting a VMT pointer (as returned by TypeOf() ) as a parameter), since it wouldn't "use up" a method name.
What about making the structure of the VMT record visible for the program? For instance a built-in
Type VmtRec = record Size, NegSize: Integer; VirtualMethod: array [ 0..1 ] of Pointer; end (* VmtRec *);
Where the `1' above stands for the unknown number of methods in a VMT.
(* I thought about changing the VMT to a schema type
Type VmtRec ( n: Integer ) = record Size, NegSize: Integer; VirtualMethod: array [ 1..n ] of Pointer; end (* VmtRec *);
which would place `n' as an additional field at the very beginning of each VMT. But it's probably better to let `Size' stay the first field and to save the additional storage for the number of methods in the object. *)
And also not put all the symbols in every programs, just those that use the "ClassName()" function,
Difficult.
optimizing those using constants as their parameter
Easier.
and so on...
Most difficult.
A unique number is a bad idea and shouldn't be used. They can change and invalidate a file containing streamed objects from compile to compile.
That's what I meant with the "how to choose" problem. When deriving it from the name in an unambiguous way, it would work. But how would that "unambiguous way" look like? A CRTC check sum? (I don't really know what that is ...;)
The way I see it, the best way is to make a legal way to directly call a specific class constructor. Like the "typed new()" function (passing an object type as the first parameter) does, but being able to put a variable there. Maybe a GPC-specific new() function?
`New' already is as GPC-specific as it could be ...
With another name of course to avoid incompatibilities...
I will think about that and let you know if I have an idea.
Greetings,
Peter
Dipl.-Phys. Peter Gerwinski, Essen, Germany, free physicist and programmer peter.gerwinski@uni-essen.de - http://home.pages.de/~peter.gerwinski/ [970201] maintainer GNU Pascal [970510] - http://home.pages.de/~gnu-pascal/ [970125]