Path: utzoo!attcan!uunet!lll-winken!ncis.llnl.gov!helios.ee.lbl.gov!pasteur!ucbvax!hplabs!nsc!voder!apple!lsr From: lsr@Apple.COM (Larry Rosenstein) Newsgroups: comp.sys.mac.programmer Subject: Re: serious code generation bug in Lightspeed C Message-ID: <453@internal.Apple.COM> Date: 20 Jan 89 18:35:52 GMT References: <6275@hoptoad.uucp> <1676@helios.ee.lbl.gov> <6315@hoptoad.uucp> <24012@apple.Apple.COM> <1858@randvax.UUCP> Organization: Advanced Technology Group, Apple Computer Lines: 54 In article <1858@randvax.UUCP> florman@rand-unix.UUCP (Bruce Florman) writes: >In article <24012@apple.Apple.COM> dowdy@Apple.COM (Tom Dowdy) writes: > >> >>If you call a function with a field from a handle based record, or >>Object Pascal object, as one of the parameters and the function >>or procedure you are calling is in another, unloaded, segment >>you will be in for a crash. The MPW 3.0 compilers check for >>this condition and warn you about it. This is true only if the value you are passing is larger than 4 bytes. Values smaller than 4 bytes are passed by value, but the Pascal compiler passed a pointer for larger values, and the called routine copies the parameter. If the parameter is a field of a handle or object (objects are implemented as handles), you have the same dereferencing problem. The key thing to remember is that a call to one of your procedures could result in the Memory Manager being called if the called routine is in an unloaded segment. Also, you have to beware of ROM calls that claim to take a value paramter but really don't. The example people always run into is DrawString. Since a string is larger than 4 bytes, the compile passes as a pointer. DrawString is in ROM so not segment is loaded, but the ROM code doesn't copy the string (for efficiency). DrawString does cause memory to move (it may load a font). The usual symptom is that the first call to DrawString results in garbage but subsequent ones do work. The MPW Pascal 3.0 compiler now tells you of all the cases where a use of an object field could result in problems because of a heap compaction. You can turn off these errors with a compile flag if you know the problem can't occur in a particular case. Also, the MPW Pascal compiler doesn't have some of the problems mentioned in this discussion (although the Lisa compiler did) when dealing with objects. For example, if x is an object type with field h, and you write: x.h := NewHandle(...) the compiler evaluates the left side of the assignment after the right side, to prevent problems. It doesn't do this in the case of explicit handles. If you write with x do h := NewHandle(...); the compiler caches the object in a register and not a pointer to its fields, so the statement is totally safe. Again, this is not true of explicit handles. -- Larry Rosenstein, Object Specialist Apple Computer, Inc. 20525 Mariani Ave, MS 46-B Cupertino, CA 95014 AppleLink:Rosenstein1 domain:lsr@Apple.COM UUCP:{sun,voder,nsc,decwrl}!apple!lsr