As High Performance Mark comments the associated
intrinsic can partly do what you want:
if (.not.ASSOCIATED(pa, pb)) ...
In many cases, using associated
with two pointer arguments will tell you whether the two targets "occupy the same storage units". In some senses this is the case when the pointers are pointing to the same target.
integer, target :: a
integer, pointer :: pa, pb
pa=>a; pb=>a
print*, ASSOCIATED(pa, pb)
Alas, things aren't so simple.
Another restriction for scalar targets is that they are not zero-sized storage. Take the following case
type t
end type t
type(t), target :: a
type(t), pointer :: pa, pb
pa=>a; pb=>a
print*, ASSOCIATED(pa, pb)
The output of this, if a variable of type t
has zero-sized storage, must be .FALSE.
, even though they are certainly the same target. The storage size of an object of type t
is an implementation detail.
The same holds for zero-sized arrays, although it is clear that the result here is .FALSE.
:
integer, target :: a(0)
integer, pointer :: pa(:), pb(:)
pa=>a; pb=>a
print*, ASSOCIATED(pa, pb)
If you have such pathological cases of the first kind that you care about there may be a possibility to consider using C addresses and Fortran 2003 C interoperability.
The c_associated
function compares the C addresses determined by c_loc
. Continuing the above code with type(t)
targets,
print*, C_ASSOCIATED(C_LOC(pa), C_LOC(pb))
may be more forgiving. Again, whether it works depends on the implementation.
This approach with C addresses will not help in the case of zero-length strings or zero-sized arrays: using c_loc
is prohibited in these cases.
To conclude, it is generally the case that ASSOCIATED(pa, pb)
returns .TRUE.
if and only if pa
and pb
point to the same target, but there are exceptions in both directions.