Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!purdue!bu-cs!dartvax!eleazar.dartmouth.edu!earleh From: earleh@eleazar.dartmouth.edu (Earle R. Horton) Newsgroups: comp.sys.mac.programmer Subject: Re: XFCN/XCMD string in LSC C v3.0 Summary: Code for portability. Keywords: A4-relative data, blessing or curse? Message-ID: <12968@dartvax.Dartmouth.EDU> Date: 9 Apr 89 01:34:56 GMT References: <12964@dartvax.Dartmouth.EDU> <28737@ucbvax.BERKELEY.EDU> Sender: news@dartvax.Dartmouth.EDU Reply-To: earleh@eleazar.dartmouth.edu (Earle R. Horton) Organization: Dartmouth College, Hanover, NH Lines: 68 In article <28737@ucbvax.BERKELEY.EDU> oster@dewey.soe.berkeley.edu.UUCP (David Phillip Oster) writes: >In article <12964@dartvax.Dartmouth.EDU> earleh@eleazar.dartmouth.edu (Earle R. Horton) writes: >> Using A4 as a base for global variables is a hack, anyway. There >>are situations I know of which will invalidate A4, making your global >>variables useless. (Dialog filter procs, for example.) >But Earle, that is exactly what the routines SetUpA4() and RestoreA4() >fix: > >The compiler puts the data in the same resource as the code, after the >code. The routine RememberA0() stashes away A0, which on entry is a >pointer to the resource itself. It staches it in the resource, but you >are going to be writing to the data area of the resource anyway, so >this is no worse. SetUpA4() saves the old value of A4, and sets A4 to >point at the remembered value. After that, you have access to globals >until RestoreA4(). Things like dialog filter procs, and other >procedures that will be called by the operating system need to use >SetUpA4() RestoreA4() to get at the code resource's globals. This is >no kludge, this is elegance compared to passing a pointer to a record >to every call. Several problems exist with this approach. The chief one is writing to the code resource. This is bad. It can lead to strange bugs on 68020 machines. Exactly where are the A4 values stored? If in the code resource, see previous paragraph. If on the stack, see the latest TechNote on SetUpA5() and RestoreA5(). Saying that something is "no worse" is not as good as taking the trouble to avoid the problem altogether. There are places where stand-alone code resources can implement "global" variables, and not risk problems with processor caches. Inside of the resource containing the code is not one of them. Furthermore, these places vary from application to application, making it impossible to do this right at the compiler level. Sure, passing a pointer to a data structure to every call may not be elegant, but it is the only method which I can think of that: a) Works for every conceivable application. b) Does not write to the code resource sooner or later. The worst thing about development-system-specific tricks like this is that they are not portable. Remember portability? When using A4-relative data in a driver or code resource, you are perhaps saving yourself some work, but you are writing code which will you can only expect to be compatible with the development system you are using right now. The original poster wanted to convert some XCMDs from LightSpeedD to MPW C. He was in trouble because MPW C does not provide A4-relative data. Coding for portability is being friendly to other programmers. Using A4-relative data is not portable. >One surprise: even if you have no globals, you still need to use >SetUpA4() and RestoreA4() to get at string constants and float >constants. Now that is a kludge! This is a compiler problem, for sure. I recommend using Aztec C as a fix to this particular problem. Aztec C will put both string constants and floating point constants in the code for you. Earle R. Horton Graduate Student. Programmer. God to my cats.