wlj1@cunixb.cc.columbia.edu (Wayne L Jebian) (09/14/90)
I've noticed some strange behavior from the TCL. Sometimes when I execute a toolbox call from within a method, I get the ubiquitous odd address error. This had me _REALLY CONFUSED_ until I tried putting the offending calls in other places: that is, in glue that put the trap calls outside the object's struct. Well, now my code doesn't break but I'm still confused. Is code (the methods) being moved around without updating the PC? I thought that the objects could be treated transparently as pointers - i.e. no locking required. The problem is not severe, but I like to avoid kludges whenever possible. Has anyone else experienced this, and if so, do you know why?? (c++)-- -Wayne Send Mail to: jtt@paradox.psych.columbia.edu
beard@ux5.lbl.gov (Patrick C Beard) (09/16/90)
In article <1990Sep14.105646.23614@cunixf.cc.columbia.edu> wlj1@cunixb.cc.columbia.edu (Wayne L Jebian) writes: # #I've noticed some strange behavior from the TCL. # #Sometimes when I execute a toolbox call from within a method, I get the #ubiquitous odd address error. This had me _REALLY CONFUSED_ until I #tried putting the offending calls in other places: that is, #in glue that put the trap calls outside the object's struct. This last sentence doesn't make any sense, really, I assume you meant that you can fix it if you call the toolbox outside of an object's method. #Well, now my code doesn't break but I'm still confused. Is code (the methods) #being moved around without updating the PC? I thought that the objects could #be treated transparently as pointers - i.e. no locking required. 1. The code/method of an object is just regular C code, and therefore it won't move unless you specifically mark the segment purgeable. 2. Objects are handles, not pointers, and therefore have to be treated with kindness. The rule is, don't assign into an object's fields if the rhs of the assignment can move memory. For example: struct MyObject { /* methods. */ void IMyObject(); /* data. */ Handle itsData; }; void MyObject::IMyObject() { itsData = NewHandle(1024); /* dangerous, NewHandle moves memory */ { Handle temp = NewHandle(1024); itsData = temp; } } The first assignment is dangerous, the second is safe. I'm guessing that this is the problem you were experiencing. Alternatively, you can lock your object: void MyObject::Lock() { HLock((Handle)this); } Use this method when you are about to do something dangerous like the above assignment. However, using temporary variables is actually faster, because you can avoid all those implicit double dereferences. -- ------------------------------------------------------------------------------- - Patrick Beard, Macintosh Programmer (beard@lbl.gov) - - Berkeley Systems, Inc. ".......<dead air>.......Good day!" - Paul Harvey - -------------------------------------------------------------------------------
egw%weaks@lanl.gov (Eric Wasserman) (09/18/90)
In article <6988@dog.ee.lbl.gov> beard@ux5.lbl.gov (Patrick C Beard) writes: With regard to objects in Think C: > 2. Objects are handles, not pointers, and therefore have to be treated > with kindness. The rule is, don't assign into an object's fields if > the rhs of the assignment can move memory. Actually this is not the case in which instance variables are a problem. Page 192 of the Think C manual states: "It is OK to assign values to instance variables, even when the expression on the right hand side may move memory." In Think C the rhs is evaluated first (including any memory shuffling) and THEN the handle reference on the lhs is evaluated. The real problem is passing the address of an instance variable to a routine which may move memory. There is an example of this in the same page in the Think C manual. I hope this helps. Eric Wasserman
phils@chaos.cs.brandeis.edu (Phil Shapiro) (09/18/90)
In article <63234@lanl.gov> egw%weaks@lanl.gov (Eric Wasserman) writes: > In article <6988@dog.ee.lbl.gov> beard@ux5.lbl.gov (Patrick C Beard) > writes: > > With regard to objects in Think C: > > > 2. Objects are handles, not pointers, and therefore have to be treated > > with kindness. The rule is, don't assign into an object's fields if > > the rhs of the assignment can move memory. > > Actually this is not the case in which instance variables are a problem. > Page 192 of the Think C manual states: "It is OK to assign values to > instance variables, even when the expression on the right hand side may > move memory." In Think C the rhs is evaluated first (including any > memory shuffling) and THEN the handle reference on the lhs is evaluated. Yes, it is OK to assign any expression to an instance variable inside any method for the object contains that instance variable. In general, you CANNOT depend on ThC completely evaluating the rhs of "=" before the lhs. Assignment to an object's instance variable within that object's method is a special case. For example: void myobj::Crash() { ivar = MoveMemory(); /* OK to do */ otherobj->ivar = MoveMemory(); /* not OK */ (**myHandle).ivar = MoveMemory(); /* not OK */ } > The real problem is passing the address of an instance variable to a > routine which may move memory. There is an example of this in the same > page in the Think C manual. Also, watch out for passing the address of an instance variable along with a function that may move or purge memory. For example: void myobj::Crash2() { /* assume OtherFunc doesn't move memory */ OtherFunc(&ivar, MoveMemory()); /* not OK, ivar may relocate before use */ } > I hope this helps. > > Eric Wasserman Me too! -phil shapiro, symantec tech support -- Phil Shapiro phils@chaos.cs.brandeis.edu
francis@magrathea.uchicago.edu (Francis Stracke) (09/25/90)
In article <1990Sep14.105646.23614@cunixf.cc.columbia.edu> wlj1@cunixb.cc.columbia.edu (Wayne L Jebian) writes: > >I've noticed some strange behavior from the TCL. > >Sometimes when I execute a toolbox call from within a method, I get the >ubiquitous odd address error. This had me _REALLY CONFUSED_ until I >tried putting the offending calls in other places: that is, >in glue that put the trap calls outside the object's struct. > >Well, now my code doesn't break but I'm still confused. Is code (the methods) >being moved around without updating the PC? I thought that the objects could >be treated transparently as pointers - i.e. no locking required. I do know that Think Pascal uses handles instead of pointers to reference the objects--but only their data should be in the block referenced. The code should be in the CODE resources like any other. The object's block of RAM just holds pointers (or something) to tell what routines to call.