Reputation: 111
I'm trying to learn Fortran2018 using gfortran
.
When playing around with pointers I noticed that there doesn't seem to be a facility to test for nullpointers. So I have two questions:
More practically speaking, in the code snippet below: How could we find out at any point during execution if assigning to p
was "safe" or not? (Possibly imagining a more complex sequence of allocate
, nullify
, and deallocate
statements.)
program test
implicit none
real, pointer :: p
! p = 333.333 ! Segfault, p is neither defined, nor allocated
! Since p is not defined, checking whether it's
! associated to a target gives arbitrary results:
print *, "Start: Pointer p associated? ", associated(p) ! Result: True or False
nullify(p) ! Now p is defined, but `null`
print *, "Nullyfied: Pointer p associated? ", associated(p) ! False
! p = 123.456 ! Still a segfault
allocate(p) ! Now p can be accessed
print *, "Allocated: Pointer p associated? ", associated(p) ! True
p = 987.654 ! Now assignment is possible
allocate(p) ! Loses the value pointed to by p.
print *, p ! Result: 0.00000000
deallocate(p) ! Now accessing p generates a segfault again.
print *, "Deallocated: Pointer p associated? ", associated(p) ! False
! Never allowed:
! allocated(p)
! p == null()
! p .eqv. null()
end program test
Upvotes: 7
Views: 1807
Reputation: 60123
One tests for null pointers using the associated()
function. It returns true for associated pointers and false for null pointers.
For undefined pointers the result is "undefined behaviour" (one can get anything).
Upvotes: 5
Reputation: 32451
In general, there is no safe way to tell whether a pointer is "ready to use", just as there is no safe way to tell whether a variable is currently defined.
The ASSOCIATED
intrinsic function may be used only when the pointer is of defined association status, but there is no comparable way to determine (within the Fortran program itself) whether the pointer is of defined association status.
If the pointer is of defined association status, ASSOCIATED
will tell you whether or not the pointer points to something (and can even be used in some cases whether it points to a particular thing) and can be used.
However, if the pointer is not of defined pointer association, an attempt to query its association status is a violation of the Fortran standard (this is stronger than the result being undefined, it means your entire program is broken).
You can help yourself by taking reasonable steps to ensure that the pointer association status does not become, or start as, undefined, but it's entirely your responsibility as a programmer to know whether or not the association status is defined.
One way to help is by setting the initial association status of your pointers:
real, pointer :: p => NULL() ! Defined association status, not-associated
real, pointer :: q ! Undefined association status
print *, ASSOCIATED(p) ! Allowed
print *, ASSOCIATED(q) ! Not allowed
end
(I won't say that ASSOCIATED(p)
tells us .FALSE.
, because that ASSOCIATED(q)
means we don't have a valid program.)
To conclude, if you're careful you can use ASSOCIATED
reliably to tell whether a pointer is associated, but you must be careful.
Upvotes: 8