[comp.sys.mac.programmer] MacApp & Think Pascal 3.0 Incompatibilities -- and a bug

tim@efi.com (Tim Maroney) (08/09/90)

In article <19659@orstcs.CS.ORST.EDU> boerned@mist.CS.ORST.EDU (Dan Boerner)
writes:
>Rich, Is Think Pascal 3.0 completely compatible with the IIci?  A friend
>of mine here at school has had problems running it on her IIci.  We are
>running 3.01 and projects that run fine on my IIx crash with System Error
>ID=12.  When she then rebuilds the project on her machine and then tries
>to "Go" she gets a Bus Error with the finger pointing to the project's
>main routine.  
>
>The particular project is a MacApp program were working on but her problems
>are not restricted to MacApp projects.  Have you had other complaints from
>users of the IIci?  Is there a patch we should get?

We have had a good number of problems with MacApp 2.0 and THINK Pascal
3.0.1 here.  There seem to be slightly more problems on the IIci but
we also get random crashes on the IIcx.  When I asked about this myself
recently, a few other people said here that they had also been having
strange problems with MacApp and Think Pascal.

I also just spent three days tracking down a genuine compiler bug.
THINK Pascal is pretty forgiving about declarations.  It is OK to declare
classes in an interface section giving them fields, arguments, and return
types of unknown types.  This is pleasant and it reduced the number of USES
you need in interface-only files.  However, it turns out that the compiler
will figure out the sizes of class instances wrong in some cases when you
do this.  We have a 13K object type which has a lot of arrays, one of which
is declared in a separate interface-only file.  We had some eight fields
in our object of this separately-declared array type.  It was crashing the
system when we looped through the arrays to initialize them.

I finally wound up stepping through the New/%_OBNEW routine.   The compiler
expands New calls to %_OBNEW, passing in a size parameter.  This was 13K,
just right.  However, the THINK Pascal UObject module then simply passes
on the class id of the object being created to MakeNewInstance, which
then gets the size from the method tables.  This size was only 9K.
In other words, the compiler disagreed with itself on the size of the
object, and used the inaccurate size.  This caused us to write past
the end of the object and crash the system.

It appears that the compiler figures out the size to use for the method
table size entry when the class is defined, and it simply makes the
incorrect assumption that any undefined field is size 4.  However, when
in an implementation section, all the types are defined and it figures
out the real size.  The compiler clearly should not figure sizes wrong
without giving some kind of warning, and clearly should not disagree
with itself.  It seems it should be straightforward to check and see
whether the compiler disagrees with itself and put out an error message.

The workaround is to make sure that any types which are other than four
bytes are declared before you use them in a class declaration.