In the following, the init_list subroutine makes a call to the reset subroutine passing the list subobject of the list_container.
The reset subroutine has the intent(inout) for the list. In this version of the code, it just sets the elements of the list to 1, 2, 3, 4. (In another version it shuffles the list; this isn't important, but shows why intent(inout) is required).
The program should print out the elements as 1, 2, 3, 4 but doesn't, showing that the call to reset doesn't work.
If I change the intent for list to intent(out) it works, but I can't use this if I change reset to do a shuffle.
I am still using 7.00 here.
module xxx
implicit none
type list_container_t
integer :: n
integer :: list(20)
end type list_container_t
contains
subroutine init_list(list_container, n)
integer, intent(in) :: n
type(list_container_t), intent(out) :: list_container
integer :: i
list_container%n = n
do i=1, n
list_container%list(i) = n-i+1
end do
call reset(list_container%list, n)
end subroutine init_list
subroutine reset(list, n)
integer, intent(in) :: n
integer, intent(inout) :: list(:)
integer :: i
do i=1, n
list(i) = i
end do
end subroutine reset
end module xxx
program test
use xxx
implicit none
integer :: i
type(list_container_t) :: list_container
call init_list(list_container, 4)
print *, 'Should print 1 to 4 but doesn''t'
do i=1, 4
print *, list_container%list(i)
end do
end program test
This is the shuffle version of reset, which replaces the above in my real code.
! In place Fisher-Yates/Knuth shuffle
subroutine reset(list, n)
integer, intent(in) :: n
integer, intent(inout) :: list(:)
integer :: i, j, k
real :: u
do i=1, n-1
call random_number(u)
j = i + floor((n-i+1)*u)
k = list(i)
list(i) = list(j)
list(j) = k
end do
end subroutine reset