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.