[comp.sys.mac.programmer] Pointer arithmetic in C w/ or w/o locked handles

tomc@mntgfx.mentor.com (Tom Carstensen) (04/16/88)

Is the problem I'm noticing with the following code
fragment the compiler, or on error:

    Handle hdl;
    char *ptr;
    long length;
    
    HLock(hdl);
    ptr = *hdl;
    
    while ( <condition> ) {
        /* ... stuff here ... */
        ptr++;
    }
    HUnlock(hdl);
    length = (long) (ptr - *hdl);

Running under The Debugger, I notice that the value
for ptr = 80023678, and the value for *hdl = 00023670,
and therefore length becomes 80000008, which is actually
a negative number.

The '8' (or 1000 binary) occurs because it is Locked - 
(only on 68000 w/ 24 bit addressing).  but when I do
pointer arithmetic, is the compiler messing up or 
should I only add Locked handles or Unlocked handles
together.

If I move the length calculation before I unlock the 
handle, then length becomes 8, and I'm ok.

:------------------------------------------------------------:
: Tom Carstensen         Usenet: tomc@mntgfx.MENTOR.COM      :
: Mentor Graphics                Delphi: CARSTENSEN          :
:                                GEnie:  XPC23637            :
:                                                            :
:     . . .  AAhh!  I see you have a machine that goes PING! :
:                                       - Monty Python       :
:------------------------------------------------------------:

darin@Apple.COM (Darin Adler) (04/19/88)

In article <1988Apr15.125337.100@mntgfx.mentor.com> tomc@mntgfx.mentor.com (Tom Carstensen) writes:
> Is the problem I'm noticing with the following code
> fragment the compiler, or on error?
> ...
> The '8' (or 1000 binary) occurs because it is Locked - 
> (only on 68000 w/ 24 bit addressing).  but when I do
> pointer arithmetic, is the compiler messing up or 
> should I only add Locked handles or Unlocked handles
> together.

The solution to this is the StripAddress trap. It is used to strip any
bits from the high byte of a dereferenced handle. You can use it like this:

	pointer = StripAddress(*handle);
-- 
Darin Adler						AppleLink:Adler4
UUCP: {sun,voder,nsc,mtxinu,dual}!apple!darin	  CSNET: darin@Apple.com

paul@morganucodon.cis.ohio-state.edu (Paul Placeway) (04/19/88)

In article <1988Apr15.125337.100@mntgfx.mentor.com> tomc@mntgfx.mentor.com (Tom Carstensen) writes:
<     ...

<     HUnlock(hdl);
<     length = (long) (ptr - *hdl);
< ...
< If I move the length calculation before I unlock the 
< handle, then length becomes 8, and I'm ok.

I would be _really_ supprised if something like this continued to work
correctly (assuming that it does allready; which it seems not to).

Personally, I wouldn't HUnlock the handle until you are done with it
(ie. _after_ the length calculation).  It is possible (although currently
unlikely) that the block that the handle points to could be moved
between the HUnlock and the last derefrence.  Race conditions like this
should be avoided -- they create bugs without adding any benifit.

		-- Paul Placeway
-=-
Existence is beyond the power of words
To define:
Terms may be used
But are none of them absolute.

alcmist@well.UUCP (Frederick Wamsley) (04/20/88)

In article <10897@tut.cis.ohio-state.edu> paul@morganucodon.cis.ohio-state.edu (Paul Placeway) writes:
>In article <1988Apr15.125337.100@mntgfx.mentor.com> tomc@mntgfx.mentor.com (Tom Carstensen) writes:
><     ...
>
><     HUnlock(hdl);
><     length = (long) (ptr - *hdl);
>< ...
>< If I move the length calculation before I unlock the 
>< handle, then length becomes 8, and I'm ok.
>
>I would be _really_ supprised if something like this continued to work
>correctly (assuming that it does allready; which it seems not to).
>
>Personally, I wouldn't HUnlock the handle until you are done with it
>(ie. _after_ the length calculation).  It is possible (although currently
>unlikely) that the block that the handle points to could be moved
>between the HUnlock and the last derefrence.  
Memory blocks can only move if you call a trap in the (documented) set
which use the Memory Manager directly or indirectly, or if you make
an intersegment call (which can potentially call _LoadSeg).

The only problem with dereferencing a handle to unlocked memory under
safe conditions is a code maintenance problem.  If you or someone else
accidentally changes the code so that it can cause memory motion, you
suddenly have an intermittent bug.

Of course keeping everything locked while in use will prevent a nasty
kind of bug, but it's unfriendly to keep anything locked longer than
necessary, even if you call MoveHHi first to keep it from fragmenting the 
heap.

Wistfully thinking about hardware memory management, I remain
-- 
Fred Wamsley  {dual,hplabs}!well!alcmist;well!alcmist@lll-crg.arpa;
CIS 72247,3130; GEnie FKWAMSLEY;ATT Mail fwamsley; USPS - why bother?
"I was just being polite, sir"  -  Lt. Worf