[comp.sys.mac.programmer] Is Technote #213 wrong?

Reid Ellis <rae@gpu.utcs.toronto.edu> (10/25/90)

This regards Technote #213, whose header is as follows:

    #213:	_StripAddress:  The Untold Story

    Revised by:	Paul Snively & Andrew Shebanow	August 1990
    Written by:	Andrew Shebanow	October 1988

    Inside Macintosh, Volume V, The OS Utilities, incorrectly documents the
    _StripAddress trap; this Technical Note correctly documents the trap and
    gives guidelines for its use.

    Changes since April 1990:  Added a discussion of why the _StripAddress
    trap should be used under certain circumstances when patching traps.

In the body of the technote, it is stated:

    You do not need to call _StripAddress before performing address
    arithmetic, since adding or subtracting two 24-bit addresses always
    results in the correct 24-bit address, regardless of the high byte
    values.

This first sentence confuses me.  The paragraph then goes on to say:

    ... Random high byte values can cause ordered comparisons on the results
    of pointer arithmetic to fail, since underflow or overflow could occur,
    so you should never test the result of address arithmetic against a value
    (only against NIL or 0).

The result of subtracting two addresses is an integer, not an address.
Addition of two addresses has no meaning whatsoever.  What goes on?  If I
have two addresses [say indices into an array] named ptr1 and ptr2, can I
meaninfully say the following?

	if(ptr2 - ptr1 < sizeof(array)) { ... }

This is of great concern to me.  I had always assumed code like this would
work as well on the Macintosh as it does elsewhere.  My guess is that the
person who wrote the above paragraph was told that pointer arithmetic would
work, but wasn't told clearly *why* it would work.  I hope this was the
case.

					Reid
--
Reid Ellis  264 Broadway Avenue, Toronto ON, M4P 1V9               Canada
rae@gpu.utcs.toronto.edu || rae%alias@csri.toronto.edu || +1 416 487 1383

d88-jwa@dront.nada.kth.se (Jon W{tte) (10/26/90)

In article <rae.656790607@fred> Reid Ellis <rae@gpu.utcs.toronto.edu> writes:
>This regards Technote #213, whose header is as follows:
>The result of subtracting two addresses is an integer, not an address.
>Addition of two addresses has no meaning whatsoever.  What goes on?  If I
>have two addresses [say indices into an array] named ptr1 and ptr2, can I
>meaninfully say the following?

>	if(ptr2 - ptr1 < sizeof(array)) { ... }

Well, if the two pointers come from the same source, at the same
time, this will work. But if you have one pointer from a dereferenced
locked handle, and one from a dereferenced unlocked handle, or
something like that, it won't work, since the address space is 24 bits,
and the high 8 bits are kept for state information (under 24bit mode)

Pointer arithmetic is performed on all 32 bits, so if you have different
state info in the different pointers, you'll get bogus results.
To be on the safe side, your code should read:

	if(StripAddress(ptr2 - ptr1) < sizeof(array)) { ... }

Note ! This will always work:

{
	struct foo * a, * b;

...
	b = &a[index];

	while (a < b) {
		...
		a++;
	}

since b is a derivate of (the same pointer as) a;

Hope this helps...

							h+


h+@nada.kth.se
"Moof!(tm)"