Today, you made me understand the save
attribute in one sentence, so thank you. Perhaps a more serious discussion about the Fortran documentation should be in order (elsewhere), and while I love the general appearance and clearness of the QuickStart, there are so many new tools to exploit it could be worthy to think about it (Sphinx supports notebooks, notebooks could support Fortran…). Since the advent of godbolt.org, I’ve been making myself simple and runnable example to test my understanding of what I was reading on this forum. I used the following to understand the save
attribute:
module test
!! This module contains...
use, intrinsic :: iso_fortran_env, only: real32, real64
implicit none
integer, parameter :: sp = real32
integer, parameter :: dp = real64
contains
subroutine mysub1(array)
real(real32), intent(in ) :: array(:)
! This routine serves to show that inside a routine, the custom
! bounds of your array are not maintained
print *, array
print *, lbound(array), ubound(array)
end subroutine
subroutine mysub2(array)
real(real32), intent(in ) :: array(:)
real(real32), allocatable :: array2(:)
! This routine shows that array2 will be deallocated when
! exiting the routine, you can call it multiple times and
! no errors will be thrown
allocate(array2, source=array)
print *, " allocating"
print *, array2
end subroutine
subroutine mysub3(array)
real(real32), intent(in ) :: array(:)
real(real32), allocatable, save :: array2(:)
! This routine shows that array2 will NOT be deallocated when
! exiting the routine, thus calling this routine in a loop
! will give you an error
allocate(array2, source=array)
print *, " allocating"
print *, array2
end subroutine
subroutine mysub4(array)
real(real32), intent(in ) :: array(:)
real(real32), allocatable, save :: array2(:)
! This routine has the save attribute, so repeated allocation would
! crash the program. However, if we allocate only if array is not
! allocated, we can use this routine AND the content of the array
! is maintained along from one call to the others
if (.not. allocated(array2) ) then
allocate(array2, source=array)
print *, " allocating"
else
print *, "not allocating"
print *, array2
end if
end subroutine
end module test
program testgrid
use, intrinsic :: iso_fortran_env, only: real32, real64
use test
implicit none
integer :: i
real(real32) :: array(-3:3)
do i = -3, 3
array(i) = real(i, kind=real32)
end do
print *, array
print *, lbound(array), ubound(array)
print *, "--------------------------"
call mysub1(array)
do i = 1, 10
! Comment/Uncomment to test
! allocatable, nosave: all good in the loop
!call mysub2(array)
! allocatable, save:
! "Fortran runtime error: Attempting to allocate already allocated variable 'array2'"
!call mysub3(array)
! allocatable, save, with conditional allocation
! The array is not deallocated from one call to the other and it will have the same
! content as the previous iterations
call mysub4(array)
end do
end program
Perhaps a collaborative document could be the starting point for a documentation, even an open GitHub repo with a bunch of Markdown documents could be a good starting point, people could propose macro topics, modifications, notes and simple examples and then work incrementally with the contents.