It can confuse when to use allocatable keyword when declaring dynamic arrays. We have two scenarios to declare the array here
First scenario (pre allocation)
real :: x(:,:)
Purpose:
Use this scenario inside the subroutine, or function when x was already allocated by the main program
program main
real, allocatable :: x(:,:)
allocate(x(5,5))
call process(x)
end program
subroutine process(x)
real, intent(inout) :: x(:,:) ! assumed-shape
! Can use x here (already allocated from main)
end subroutine
Second scenario (deferred allocation)
real, allocatable :: x(:,:)
Purpose:
Use this scenario inside the main or caller subroutine (function). This deferred array will be passed through and allocated inside the calling subroutine or function.
program main
implicit none
real, allocatable :: A(:,:)
integer :: m, n
m = 4
n = 3
call create_matrix(A, m, n)
print *, 'Matrix A:'
print *, A
end program
subroutine create_matrix(x, m, n)
implicit none
integer, intent(in) :: m, n
real, allocatable, intent(out) :: x(:,:) ! Note: allocatable with intent(out)
integer :: i, j
allocate(x(m, n))
do i = 1, m
do j = 1, n
x(i,j) = real(i * 10 + j) ! Just fill with dummy values like 11, 12, ...
end do
end do
end subroutine
It's important to master this concept because this will cause compile errors and be hard to debug.