Peter N Lewis wrote:
At 9:44 -0800 10/12/07, Scott Moore wrote:
John L. Ries wrote:
There probably wouldn't be anything wrong with GPC automatically setting pointers to nil when disposing them, but that would be non-standard and I suspect that most people (myself included) would do it themselves anyway (for portability's sake) unless the pointer was going to be immediately reassigned.
No, that's perfectly ok with the standard. It simply specifies that the value is undefined, which means set to nil is as good as anything else.
I do not believe that is correct.
I'm pretty sure the semantics for dispose are that it takes a value parameter, and so has no ability to modify the pointer.
As much as I might prefer the definition to be that the pointer is set to nil, and like Adriaan, my preference is for wrapper functions that are nil-safe and idempotent, changing the behaviour of dispose could make correct code fail.
For example, imagine this pseudocode:
p = New pointer. AddToListOfPointers( list, p ); Dispose( p ); RemoveFromListOfPoitners( list, p );
That is perfectly legal code, but would fail if dispose became a by reference, set to nil procedure.
As Adriaan described, if you want that facility, simply write your own wrappers.
My own wrappers included:
- nil-safe
- nil-setting
- leak checking code
- memory trashing
Enjoy, Peter.
Well, you could always "discover" that the expression qualifies as variable reference. I think the only thing that having a pointer as an expression gives over variable references is the ability to include function returns, since pointers are inadmissible to any operator save those that don't deliver a pointer in any case (p = x, p <> x).
For your second point, I see what you are getting at, but you might want to look closely at the standard there:
Dispose( p ); RemoveFromListOfPoitners( list, p );
ie,. what is the value of p? Your code implies p remains the same.
6.6.5.3 Dynamic allocation procedures
new(p) shall create a new variable that is totally-undefined, shall create a new identifying-value of the pointer-type associated with p, that identifies the new variable, and shall attribute this identifying-value to the variable denoted by the variable-access p . The created variable shall possess the type that is the domain-type of the pointer-type possessed by p.
...
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).
...
NOTE -- The removal of an identifying-value from the pointer-type to which it belongs renders the identified-variable 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).
ie., dispose indeed takes a value parameter, which it is NOT supposed to change, but here the standard seems to say that it is, indeed changed, to undefined.
This says at the least "don't count on the value", but it can be interpreted as room to implement a recycling system that finds and invalidates pointers, even non-obvious ones. In that case, the code shown would not work.
Either way, we agree it's a bad idea.
Scott Moore