My recent mailing was of course wrong. All who replied waving the
F90 standard were right.
BUT. I still don't like the behaviour prescribed by the Fortram standard.
Having pointers in undefined states is unsafe, is --as I was reminded--
beyond the control of the programmer but the programmer is held
responsible. This is too onesided. I tried to think of a way around it
within the constraints of the Fortran standard but that is not possible
as several comments pointed out my errors.
Until I realized that my initial gut reaction was right and the culprit
is the Fortran standard.
Why? Because Fortran committees avoided (weazled out of) a correct and
proper solution for this important safety problem and left the Fortran
programmer with onus of getting an impossible task right.
The problem is the well-known dangling pointer problem. Example:
real, pointer :: a, b
allocate( a ) ; a = 1.0
b => a
deallocate( a )
Pointer b is left dangling after deallocation of a. Everything would be fine
if one just nullified a. The standard clearly says when a pointer becomes
undefined (dangling) and these are essentially variations of the above
example.
How can one avoid the dangling pointer problem?
Simply by not deallocating the memory. As long as an object in memory has
potential references in the programme it must not be deallocated (freed).
It is a much too complicated job for a programmer to worry about memory
management in detail. This should and must be left to a GARBAGE COLLECTOR
(GC). Yes right, that is the only sound and safe way of handling memory.
(Modern GCs are quite efficient and of course much better at reclaiming
unused memory than any human programmer. And why reinvent the wheel
again and again.)
Before anybody gets to scared about this, some memory management can be
done quite safely by the programmer, viz. the allocation and deallocation
of ALLOCATABLE variables without the TARGET attribute. And that is quite
a large chunk in the typical Fortran programme.
However, any object in memory that can be accessed in several ways can
not be handled safely by the programmer, it must be done through GC.
That is in constructs like
real, dimension(:), allocatable, target :: t
real, dimension(:), pointer :: p, r, s
allocate( t(100) )
allocate( p(100) )
r => t
s => p
t and p should never be DEALLOCATEd but just nullified (pointers) or detached
(allocatable targets):
detach( t ) ! ALLOCATED(t) = FALSE
nullify( p ) ! ASSOCIATED( p ) = FALSE
This leaves r and s still properly associated with the respective objects
in memory.
Local variables inside a procedure can be targets and pointed to by
actual arguments. This requires some extra rules/constraints.
For example, one could just disallow a non-local pointer to point
to a local procedure target:
subroutine foo( p )
real, pointer :: p
real, target :: t
p => t ! Bad, disallow it because t and its memory
! ceases to exist after return
end subroutine foo
However,
subroutine foo( p )
real, pointer :: p
real, pointer :: temp
allocate( temp )
p => temp
end subroutine foo
is fine since temp should only be nullified at the exit of foo and not
deallocated. (This is important for handling dynamic data structures.)
These rules are the basis for safe and sound handling of memory and
sufficient in all (nearly all?) situations. (I would claim that any
case for the "nearly all" version has some flaw which would exclude it
as a counter example.)
With this basic outline there is no need for an undefined state of
pointers anywhere in a Fortran programme. It shifts the responsibility
for memory handling to where it belongs, away from the programmer and to
the run-time system.
Whether the Fortran standard will eliminate the undefined state is a
different matter since backward compatability crops up and the above
solution is safe but not fully backward compatible.
Cheers,
WWS
-----------------------------------------------------------------------
| Werner W Schulz |
| Dept of Chemistry email: [log in to unmask] |
| University of Cambridge Phone: (+44) (0)1223 336 502 |
| Lensfield Road Secretary: 1223 336 338 |
| Cambridge CB2 1EW Fax: 1223 336 536 |
| United Kingdom WWW: |
-----------------------------------------------------------------------
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|