Scott Moore wrote:
From: Russell Whitaker russ@ashlandhome.net
On Mon, 10 Dec 2007, Scott Moore wrote:
[..]
What did you expect to happen?
I expected "dispose" to undo what "new" does. Could not find a comment in gpc's source that states otherwise.
At present,
new(p)
- allocates a block of memory from the heap, the size is the size that p wants to point to.
- returns the address of that memory block.
dispose(p)
- marks the block of memory that p points to as free. (I say "marks" because the block doesn't disapear)
Thus, this works, but shouldn't:
writeln( p^ ); dispose( p ); writeln( p^ );
============================================= 6.5.4 Identified-variables An identified-variable shall denote the variable, if any, identified by the value of the pointer-variable of the identified-variable (see 6 .4 .4 and 6 .6 .5 .3) shall be accessible until the termination of the activation of the program-block or until the variable is made inaccessible (see the required procedure 28 ISO/IEC 7185 :1990(E) dispose, 6.6 .5 .3). NOTE | The accessibility of the variable also depends on the existence of a pointer-variable that has attributed to it the corresponding identifying-value. A pointer-variable shall be a variable-access that denotes a variable possessing a pointer-type . It shall be an error if the pointer-variable of an identified-variable either denotes a nil-value or is undefined. It shall be an error to remove from the set of values of the pointer-type the identifying-value of an identified-variable (see 6 .6 .5 .3) when a reference to the identified-variable exists. Examples: p1fi p1f .fatherf p1's .sibling's .father's 6.5 =========================================================== The statement "writeln( p^ );" after dispose is an "error", dispose left p undefined.
If you dig into gpc's heap.pas you will find code that is the equivalent of:
if p <> nil then dispose(p);
What I'd like to see is the equivalent of:
if p <> nil then begin dispose(p); p := nil; end else writeln( stderr,"WARN: illegal use of dispose");
In places the specs are hard to follow, but I think the specs would allow this.
Russ
====================================================== 6.6 .5.3 Dynamic allocation procedures
...
dispose(q)
shall remove the identifying-value denoted by the expression q from the pointer-type of q . It shall be an error if the identifying-value had been created using the form new(p,c l , . . .,cn).
dispose(q,kl , . . .,km)
shall remove the identifying-value denoted by the expression q from the pointer-type of q . The case-constants k 1, . . .,km shall be listed in order of increasing nesting of the variant-parts . It shall be an error unless the variable had been created using the form new(p,c 1 , . . .,cn ) and m is equal to n . It shall be an error if the variants in the variable identified by the pointer value of q are different from those specified by the values denoted by the case-constants k 1, . . .,km.
NOTE | The removal of an identifying-value from the pointer-type to which it belongs renders the identifiedvariable inaccessible (see 6 .5.4) and makes undefined all variables and functions that have that value attributed (see 6 .6 .3 .2 and 6 .8 .2 .2).
It shall be an error if q has a nil-value or is undefined.
So, again, it is an error (to pass nil to dispose). However, the standard leaves it up to the implementation when and if such errors are detected, so this is a "quality" issue:
================================================= 3.1 Error A violation by a program of the requirements of this International Standard that a processor is permitted to leave undetected. ==================================================
I'll bet a nickel that the dispose nil behavior you saw was designed to compensate for disposals of zero length data. I had to solve that problem, but did it using a key address, i.e., new() returns a specific, predefined location that is the universal zero length pointer.
Scott Moore