I would like to have an associate that points to an array (or parts thereof) and is not one indexed. The following program illustrates the problem:
program test_associate
implicit none(type, external)
integer, parameter :: N = 10
integer :: i, A(0 : N - 1)
A = [(i, i = lbound(A, 1), ubound(A, 1))]
write(*, *) A(0), A(9)
associate(B => A(0 : N - 1))
write(*, *) B(9) ! This writes 8 but should write 9
end associate
end program
I tried
associate(B(0 : N - 1) => A(0 : N - 1))
write(*, *) B(9)
end associate
but this is invalid syntax. (at least in my compiler which is gfortran 9.3)
The syntax
associate (B(0:N-1) => ...)
end associate
is not valid in Fortran: the left-hand side of the association item must be a name. With just a name (which here would be B
) it isn't possible to specify properties such as bounds.
The bounds of the associating entity array (again, here B
), are given by the results of using LBOUND
on the right-hand side (the selector) (Fortran 2018, 11.1.3.3 p.1):
The lower bound of each dimension is the result of the intrinsic function
LBOUND
(16.9.109) applied to the corresponding dimension of selector
The referenced description of LBOUND
explains how the bound is calculated in this case.
Because A(0:N-1)
is not a whole array, LBOUND
returns 1
, and so the lower bound of B
in this case is itself 1
.
It is possible to have the lower bound of B
be something other than 1
: have the selector being a whole array. In
associate(B => A)
end associate
B
will have lower bound that of A
.
In conclusion: it's possible for an associate entity to have lower bound other than 1
, but only when the thing it's associated with is a whole array. In particular, in associating with part of an array (and that can include all of the array, such as B => A(:)
, A(:)
not being a whole array) the associating entity always has lower bounds 1
.
As Vladimir F says in another answer, a pointer can have bounds controlled as part of pointer assignment.