[comp.sys.mac.programmer] StripAddress and pointer arithmetic

bruner@sp15.csrd.uiuc.edu (John Bruner) (05/26/90)

I've just read the technical note on StripAddress (#213, April 1990).
On the second page under the (sub)heading "Ordered Address Comparison"
it says

	If you need to sort by address or do any other kind of
	ordered address comparison, you need to call _StripAddress
	on each address before doing any ordered comparisons
	(>, <, >=, <=).  Remember, even though the CPU only uses
	the lower 24 bits in 24-bit mode, it still uses all 32 bits
	when performing arithmetic operations.

Taken literally, this means that it is unsafe to write

	struct something *p, things[64];

	for (p = things; p < things + 64; p++)
		...

because one can't rely upon the comparison "p < things+64" working.
This type of expression is very common in C (and is sanctioned by the
ANSI standard).  I don't really believe this will fail, because the
high bits in the expressions "things" and "things + 64" will almost
certainly be the same (unless it would wrap in a 24-bit address
space).

I believe I understand what will and will not behave as expected, but
I think it should be spelled out better.  The way I read this
technical note the Macintosh cannot (efficiently) support an
ANSI-compliant implementation of C.
--
John Bruner	Center for Supercomputing R&D, University of Illinois
	bruner@uicsrd.csrd.uiuc.edu	(217) 244-4476	

mystone@mondo.engin.umich.edu (Dean Yu) (05/26/90)

In article <1990May25.194025.9751@csrd.uiuc.edu> bruner@sp15.csrd.uiuc.edu (John Bruner) writes:
>I've just read the technical note on StripAddress (#213, April 1990).
>On the second page under the (sub)heading "Ordered Address Comparison"
>it says
>
> [Passage from TN 213 deleted]
>
>Taken literally, this means that it is unsafe to write
>
>	struct something *p, things[64];
>
>	for (p = things; p < things + 64; p++)
>		...
>
>because one can't rely upon the comparison "p < things+64" working.
>This type of expression is very common in C (and is sanctioned by the
>ANSI standard).  I don't really believe this will fail, because the
>high bits in the expressions "things" and "things + 64" will almost
>certainly be the same (unless it would wrap in a 24-bit address
>space).
>

  Actually, this would work.  The Tech Note was working under the assumption
that the pointers/handles you were sorting were unrelated, and might have their
high byte in different states.  (Some locked, others purgeable, etc...)  Since
you're assigning p to thing, the two are refererencing the same address, so
comparisons, sorts, and all that fun stuff would work fine.

_______________________________________________________________________________
Dean Yu                            | E-mail:    mystone@caen.engin.umich.edu
Mac Support &                      | Real-mail: Dean Yu
 Self declared License Czar        |            Rm 145 Chrysler Center
University of Michigan             |            2121 Bonnisteel
Computer Aided Engineering Network |            Ann Arbor, MI 48109
     INCLUDE 'Disclaimers.a'       | Phone:     (313) 763-3070
-------------------------------------------------------------------------------

beard@ux1.lbl.gov (Patrick C Beard) (05/27/90)

In article <1990May25.194025.9751@csrd.uiuc.edu> bruner@sp15.csrd.uiuc.edu (John Bruner) writes:
#I've just read the technical note on StripAddress (#213, April 1990).
#On the second page under the (sub)heading "Ordered Address Comparison"
#it says
#
#	If you need to sort by address or do any other kind of
#	ordered address comparison, you need to call _StripAddress
#	on each address before doing any ordered comparisons
#	(>, <, >=, <=).  Remember, even though the CPU only uses
#	the lower 24 bits in 24-bit mode, it still uses all 32 bits
#	when performing arithmetic operations.
#
#Taken literally, this means that it is unsafe to write
#
#	struct something *p, things[64];
#
#	for (p = things; p < things + 64; p++)
#		...
#
#because one can't rely upon the comparison "p < things+64" working.

Ok, time for a clarification.  Note that your example implies variables
that are allocated on the stack.  This code will always work.  Address
arithmetic only has problems when you are dealing with addresses that
might be dereferenced handles, or "master pointers".  This is because
the *current* memory manager keeps state information in the high byte
(actually high nibble) of master pointers (i.e. if a handle is locked,
purgeable, or a resource).  These bits will throw off address comparisons
obviously, and so StripAddress is in order.  In general, addresses
are clean.  Examples of where they might not be include:  dereferenced
handles, code resources dereferenced then called will put garbage in
the pc, and so should be stripped before being called.

A 32-bit operating system will make all this stuff go away.  Let's hope
we get it soon.

-------------------------------------------------------------------------------
-  Patrick Beard, Macintosh Programmer                        (beard@lbl.gov) -
-  Berkeley Systems, Inc.  ".......<dead air>.......Good day!" - Paul Harvey  -
-------------------------------------------------------------------------------

shebanow@Apple.COM (Andrew Shebanow) (05/31/90)

In article <1990May25.194025.9751@csrd.uiuc.edu> bruner@sp15.csrd.uiuc.edu (John Bruner) writes:
>Taken literally, this means that it is unsafe to write
>
>	struct something *p, things[64];
>
>	for (p = things; p < things + 64; p++)
>		...
>
>because one can't rely upon the comparison "p < things+64" working.

I wrote that Tech Note, and I agree that it could be clearer (sigh).

The type of loop you show above will work fine without calling StripAddress.
The only time you have to worry is if you are comparing two arbitrary
(and possibly unrelated) addresses (for instance, if you compare a pointer
parameter to a pointer stored in a list when doing a sort by address).

Sorry for the confusion,

Andrew Shebanow
DTS Emeritus
Apple Computer, Inc.