I have experimented with the ASSOCIATE and have come up with some “rules” about how it works. (Of course, the true rules are defined in the standard.) A few things did surprise me. The rules are illustrated with a code, where (n) in a comment indicates which rule applies. Since I may tweet about this, corrections are especially welcome.
The LHS and RHS of an ASSOCIATE statement are termed the associate-name and selector.
associate (pi => 3.14) ! pi is associate-name, 3.14 is selector
(1) Each ASSOCIATE statement must be followed by an END ASSOCIATE
(2) If ASSOCIATE appears in a loop, END ASSOCIATE must appear in the same loop.
(3) If the selector of an ASSOCIATE is a variable, the associate-name
can be changed in an ordinary assignment, which also changes the variable.
(4) If the selector of an ASSOCIATE is an expression, the associate-name
cannot be changed in an ordinary assignment.
(5) An associate-name can appear in an ASSOCIATE statement even if it previously
appeared in an ASSOCIATE statement that has not been terminated.
(6) The associate-name is not ALLOCATABLE even if the selector is, so it
stays the same size within the ASSOCIATE construct. If the selector is
an unallocated allocatable array, the associate-name is a zero-size array.
program demonstrate_associate
implicit none
integer :: i,j
integer, allocatable :: v(:), w(:)
do i=1,3
associate (x => real(i))
print*,i,sqrt(x)
end associate ! (1) must appear here, not after end do
end do
j = 2*i
associate (n => i)
n = 10
associate (n => 2*n)
print*,"@ n=",n
! (4) n = 100 ! invalid -- cannot change n when it is assigned an expression
associate (n => 2*n) ! (5) n is associated to a new value
print*,"@@ n=",n
v = [10,20]
associate (c => v, d => w) ! (6) c and d are not allocatable even though v and w are
c = [2,4]
print*,"c =",c
w = [10,20]
print*,"d =",d ! (6) d has zero size even though size(w) = 2
! d = [10,20] ! (6) invalid since d has zero size and is not allocatable
end associate ; end associate ; end associate; end associate
end program demonstrate_associate
! output with gfortran and Intel Fortran:
! 1 1.000000
! 2 1.414214
! 3 1.732051
! @ n= 20
! @@ n= 40
! c = 2 4
! d =