You could change
subroutine knuth_shuffle(array, length)
implicit none
integer :: length
integer :: array(length)
integer :: randomIndex
integer :: temp
to
subroutine knuth_shuffle(array)
implicit none
integer :: array(:)
integer :: length
integer :: randomIndex
integer :: temp
length = size(array)
or you could just chuck away the local variable length
and write
subroutine knuth_shuffle(array)
implicit none
integer :: array(:)
integer :: randomIndex
integer :: temp
integer :: i
do i = 1, size(array) - 2
randomIndex = floor(randomBetween(real(i), real(size(array))))
temp = array(i)
array(i) = array(randomIndex)
array(randomIndex) = temp
enddo
end subroutine knuth_shuffle
While I'm answering: the subroutine doesn't know or care if the actual argument supplied as array
is allocatable or static. There is nothing in the subroutine that is affected by, nor which affects, the allocation status of the array. From the subroutine's perspective array
is of assumed-shape, on which point see this question and answer.
As @francescalus has commented, if it has assumed-shape array arguments the procedure requires an explicit interface The easy way to provide that is to have the compiler generate the interface; either (preferable) put the procedure in a module
and use
it or (more limited applicability) include it within the contains
section of another program unit (maybe the main program unit). A last resort, generally only to be taken when modifying old code, would be to write an interface
block yourself.