OOP_(re)

Tue, 3 Jun 1997 23:57:25 +0200 (MET DST)


According to Frank Heckenbach:
> 
> According to myself (Peter Gerwinski):
> 
> > The only problem with this:  As I wrote, I am initializing the object
> > *outside* the constructor's body.  If I enable virtual constructors, this
> > must not change any more.
> 
> I don't think it's a problem, because if a constructor is called virtually,
> the object must have been initialized before (otherwise the constructor's
> address couldn't be found).

It's done like this at the moment, but BP does it in another way.
As long as I don't know why (i.e. I suspect some disadvantages of the
method used currently which didn't show up yet), I am very careful about
fixing it.

> (I'm assuming, "initializing" means only setting
> the VMT link, or does it do anything more?)

Yes.

(Read: The `or' condition holds; one of both is `true'.  (The first.;))

> But there is another problem, namely to decide whether to call the
> constructor virtually (i.e. looking up its address via the VMT) or
> "statically".

What's the problem?  It's just calling another virtual method.

> If there's a reliable way to detect if an object has been
> initialized (like we discussed earlier), this would be easy (virtually if
> initialized, statically otherwise).

It is possible:  I would have to pre-initialize (set the VMT to zero)
each object variable when created:  global variables at startup time, local
variables when the procedure is entered, dynamical variables when `new'ed
(without constructor call which would make the pre-initialization
superfluous).

> This means that Fillchar'ing an object with 0 is a bad idea (even if you
> exclude the VMT link)!
> So, Pierre, it seems like you'll have to renounce this feature from TV.

As I wrote in my other mail, it must be present in BPcompat's "Objects"
Unit for compatbilitie's sake.

> > [`Interface' keyword ...]
> 
> As a scientific model, it seems good (unifying as much as possible), but
> I think in actual programs, it's easier to distinguish by using different
> keywords. Perhaps the rules are also more comprehensible this way, and
> programmers familiar with Delphi or Java will recognize what they know.

Agreed.

> I could perhaps help with designing the structures and algorithms (see
> below ;-), if desired,

Yes, please!

> but probably not with hacking the compiler...

Why not?  GPC doesn't bite!  (-; If it does, this is a bug which must be
reported! :-)

(* There is only one problem with hacking GPC:  It's addictive ... :*)

> > > - Its type is a 64/128 bit integer.
> >
> > Really?  In David's example it's a string constant!
> >
> >     const
> >         SIID_IActiveScriptSiteWindow = '{D10F6761-83E9-11cf-8F20-00805F2CD064}';
> 
> Yes, I saw this too, but didn't spend much thought about it.
> This string constant looks suspiciously like a 32-digit hex number, i.e. a
> 128 bit integer. Does Delphi convert this to an integer internally (Delphi
> users, please!)?

I cannot believe that.  Why should they enter it as a String constant, then?
And there are braces, etc.  No, I believe that this is indeed a string to be
interpreted by some program lying around somewhere ... so we should provide a
string, too. :-|

> Anyway, I think at least in gpc the internal representation should be an
> integer, not a string.

Since that other program obviously wants the number as a string surrounded by
braces, this would be no good idea with respect to compatibility.

> [Representing pointers to interfaces as multiple pointers ...]

I understand that this will work, but I fear the many special cases it would
cause to implement a non-standard-format pointer:  They would be allowed in
all contexts where "ordinary" pointers are allowed, so all internal GPC
routines handling pointers would have to be modified. :-(

BTW, using this method, we could also implement pointers to "ordinary" objects
thus saving the VMT field in each instance.  It's kind of an "external field"
for each object instance ...

> You mean something like the following?
> 
> VMT of T:
> Offset Field
>   0    Size
>   4    NegSize
>   8    [... perhaps ObjID and such]
>  20    Offset of I, i.e. Pointer to I1 in *this* VMT
>  24    Offset of J, i.e. Pointer to I2 in *this* VMT
>  28    M1
>  32    M2
>  36    I1
>  40    I2
> 
> V:
> Offset Field
>   0    Pointer to VMT of T
>   4    4 (Interface offset I)
>   8    8 (Interface offset J)
>  12    F1
>  16    F2

Yes.

> An interesting method, AFAICS it will work, too.
> 
> The disadvantage is that instances and VMTs get bigger. In my method,
> pointers to interfaces get bigger, so that's a tradeoff.
>
> I think, however, that pointers to interfaces are rarer (and mostly they
> appear as parameters, i.e. only temporarily), so my method might be a bit
> more economical with memory.

I am not sure about that.  Remember that most objects will contain pointers
to interfaces if an interfaces is implemented at a relatively low place in
the object hierarchy.  Then they will be blown up - perhaps more than they
would if getting one integer field for each inherited interface.  Furthermore
I think that pointers are often used in structures where the programmer wants
to save space for some reason, while object instances are allocated on the
heap and usually aren't expected to be "small".

Facing the enormous technical problems with your method I am preparing to
implement mine.  :(Yours is nice too - sorry - and very innovative.  Perhaps 
you want to try yourself on it?:)

> [Lots of interesting technical details snipped ...]

> > > There may be some types that need a persistent ID (i.e. one that cannot
> > > simply regenerated with each storing, for whatever reason), but then again,
> > > ID should be a field of these special types only.
> >
> > I have *lots* of such types,
> 
> Really -- their IDs must be the very same in a different program run?
> If so, why? I'm asking just out of curiosity.
>
> [...]
>
> But I still can't understand why you can't simply use the pointer from the
> beginning, i.e. when you assign IDs (like "Factor1ID := Factor1^.ID"), you
> just do "Factor1ID := @Factor1". Then you have the pointer when you need it.
> Is it that the whole object "Factor1" can change (be reallocated), not only
> its contents change -- the "aliasing bug"?  [...]

The object may be reallocated, but it also may vanish completely.

Here is an example from praxis.

We have a CAD program dealing with staircases.  Suppose that the desktop
currently contains one dialog holding numerical data about the staircase plus
zero or more drawings of the staircase from different view points.  Now the
user changes one value in the dialog.  We want all drawings to update
immediately.

Since it is not clear which drawings are currently on the desktop, the dialog
does not have pointers to them.  (More precisely: It has pointers but must
ensure from time to time that they are still valid.)  Instead, it sends a 
message to all windows and asks for drawings currently displaying "this" 
staircase.  To specify the "this", the unique ID of the staircase object
(as entered by the user) is used.

The other direction is more interesting and makes more trouble at the moment
*because* we use pointers instead of IDs.  Each drawing has a pointer to the
staircase it is displaying.  (For obvious reasons, it is necessary for the
drawing to know about the staircase.)  Now the user may decide to close the
staircase dialog and to continue his work only with the drawing(s).  Then the
pointer becomes invalid, and we must do some administrative work to set it to
`Nil' at exactly the correct time.  The ID of the staircase however would
remain valid; a "search the staircase" function could return `Nil' now or even
decide to reload the staircase from disk.

(More about this on demand.;)

> [`is' operator and abstract objects snipped]

> This sounds like a bad design of TV (no surprise to me...). If designed well,
> changes should only be necessary in relatively few places.

I agree this is a design fault in TV, but I doubt that it's is possible to
design a class library which will never need changes in the innermost part ...

(That's what new, incompatible versions are for.)

> Of course, if changes are made to "gpc's TV" to make it more easily adaptable
> to graphics mode (or whatever), these changes could go into the main
> distribution. The actual graphics mode changes (which should be rather few
> then) should go into a separate package.
>
> If this doesn't work well (i.e. if many diffs between text and graphics
> version remain), this might be an indication that TV and TV/graphics are
> simply different enough to not share the same classes. (And actually, one
> would hardly ever use objects of both packages in the same program.) So they
> could be simply two packages with "similar" source then...

Here I disagree.  I have written some programs which can run, on demand, in
text mode as well as in graphics mode, and *all* objects are shared between
"both packages" (which are in fact one).

> [Borland TV miseria ...]
> 
> > And let us work on
> > something which will make the world forget that TV did ever exist!  :-)
> 
> ...and Borland as well (if they behave like this) -- sad to say so...

Sad, but I agree.  I always hoped that they would be a "counterpart" of M$,
but since they obviously don't intend to support anything non-M$, they seem
more like "BG's dog" for me ...

> > I have attempted to compile TVision with GPC, but it lacked to much object
> > support.
>
> ...and x86 real mode assembler support, I suppose... ;-(

What is missing in BP7 object support?

I think we are not too far away from having a GPC which can compile (a patched
version of) TV.  Some assembler sections would have been re-written
completely; some assumptions about internal representations would have changed
(or - even better - wiped out), but in essential, GPC meanwhile supports most
of BP7.  Now it must become more stable ...

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]


Peter Gerwinski (peter@agnes.dida.physik.uni-essen.de)

HTML conversion by Lluís de Yzaguirre i Maura
Institut de Lingüística Aplicada - Universitat "Pompeu Fabra"
e-mail: de_yza@upf.es