January 90 - COMPATIBILITY-RULES OF THE ROAD
COMPATIBILITY-RULES OF THE ROAD
DAVE RADCLIFFE
Apple's System Software Version 7.0 provides the most important test of
compatibility since the introduction of the Macintosh II. This article should help you
prepare for the release of System 7.0. For an overview of the most critical
compatibility issues and how to address them, read on.
If you've already read too many stuffy articles full of dire warnings about
compatibility, you've probably decided this one will be best suited for lining the
bottom of your filing cabinet. But before doing that, consider the case of Johnny
Appledweeb.
Ace Macintosh programmer for Cliff Grazer Enterprises, Johnny is currently putting
in the long hours to get a spread-processor-terminal-graphics-emulator out the door.
He doesn't have time to read an article like this because Cliff Grazer, his boss and
President of CGE, is all over his case. Four months ago, the company began accepting
prepayment from customers who can't wait for Johnny's program to reach their local
stores. Those customers are now beating down the doors.
Although Cliff is desperate to get the product out, he has required certain levels of
performance. The application must be kept under the 1megabyte limit, for example,
and must keep up at 19.2 kbaud through the modem port. Finally, at the last minute,
legal decides to require copy protection. Once the application ships, reviews are
excellent, customers are happy, and sales are good. Cliff is ecstatic and gives Johnny a
big raise. Johnny has time to relax a bit and maybe even catch up on some reading.
But this article doesn't interest him because he's a crack programmer, and his
application works fine. Bottom of the filing cabinet time.
Six months later, Johnny comes back from his well-earned vacation to find that Apple
has introduced new machines and released a new version of the system software.
Cliff's hopping mad because of reports of compatibility problems and complaints from
angry customers. As Johnny begins to look into the problems, he has a vague
recollection of some article he saw on compatibility. He rummages around, finds the
article, and quickly discovers it addresses his problems. But it's too late for the
customers. They don't understand compatibility, but they do understand that the
application they have been using every day no longer works. Cliff doesn't really
understand compatibility either. What he understands is he now has the expense of
shipping updated versions to keep his customers happy.
Johnny might have saved himself and others a lot of trouble if he'd spent a few minutes
with this article right away. Sure, it probably would have meant a delay in the first
release of the application, but it might also have made a second release unnecessary.
Johnny's a good programmer, and he's aware of almost everything in this article, but
if a single sentence had helped avoid problems, the article would have been worth
Johnny's time.
It may be worth your time as well to check out the compatibility of your current
application's features with System 7.0. The road gets a little dry and dusty from here
on, so grab a cold one and we'll get down to business. This article focuses on specific
areas of Macintosh programming where compatibility might trip you up today or in
the future. It isn't meant to be a guide to Macintosh programming, so if you need
additional information on a topic, such as implementation details, refer to Inside
Macintosh, volumes I-V, and the Macintosh Technical Notes.
DEFENSIVE PROGRAMMING
Murphy was clearly a computer engineer. If anything can go wrong with your
application, it will, as most of us learn the hard way. Once you recognize that users
always stress your program in ways you never thought possible, you acquire defensive
programming habits.
TESTING
Always test return values for possible errors because you never know when some
unusual situation will arise. Assume that data structures will change. The Memory
Manager is an example of a manager whose data structures are changing, as described
later in this article. Avoid any portion of a data structure marked "Unused"--its use
is reserved for Apple.
MEMORY ALLOCATION
If you treat the Memory Manager with a little courtesy and respect, your application
will live a long and happy life. Keep in mind the strengths as well as the limitations of
the Memory Manager and listen to what it tells you. Believe it when it returns a nil
handle to tell you of memory allocation failure. Every application's memory needs are
different, and as you design your application, think about how memory you allocate
will be used. A little planning can ease the Memory Manager's task by reducing the
number of Memory Manager calls and minimizing fragmentation and thrashing.
You should ask yourself a few simple questions about the memory you allocate in the
heap. Is this memory you will need frequently? Rather than frequently allocating and
releasing the memory, wouldn't it be better to allocate it once at the start of your
application if it is a handle, move it high in the heap with MoveHHi and simply reuse it
when necessary?
Is it memory that shouldn't move? If so, consider the use of NewPtr instead.
Is this a large block of memory used for a very short period of time? Judicious use of
MultiFinder temporary memory can satisfy such needs and reduce overall heap usage,
allowing you to shrink your MultiFinder size partition.
Is this memory you are willing to let the Memory Manager dispose of at its discretion,
such as for a resource? Then you should consider making it purgeable. But if you've
made it purgeable, be sure to check for empty handles.
Once you have your application working, be sure to stress test your use of the Memory
Manager. You can do this by using your debugger to force heap scrambling and
purging. You can also simulate low memory conditions by running your application in
a small MultiFinder partition.
32-BIT CLEANLINESS
Another way to treat the Memory Manager with kindness and respect is to practice
32-bit cleanliness. Being 32-bit clean may be the single most important
compatibility issue facing developers. To understand what 32-bit cleanliness means,
let's take a closer look at Macintosh memory management. The Memory Manager
maintains free-form memory structures called heap zones. It allocates memory
blocks of various sizes within these zones to satisfy memory allocation requests by the
system and applications. Occasionally, heaps will become full or fragmented and the
Memory Manager will need to rearrange or purge blocks in a zone to create enough
contiguous space to satisfy a memory allocation request. To minimize confusion that
could occur when blocks are rearranged, the Memory Manager uses indirect
references called handles to refer to relocatable blocks in the heap.
The Memory Manager maintains a series of master pointers referring to blocks in