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) 1. allocates a block of memory from the heap, the size is the size that p wants to point to. 2. returns the address of that memory block.
dispose(p) 1. 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