3

I read on many posts on Stack Overflow that an allocatable array is deallocated when it is passed in a subroutine where the dummy argument is intent(out).

If I consider the following code :

program main

 real, dimension(:), allocatable :: myArray
 integer :: L=8

 allocate(myArray(1:L))
 call initArray(myArray)
 print *, myArray
 
contains

 subroutine initArray(myArray)
 real, dimension(:), intent(out) :: myArray

 myArray(:) = 10.0
 
 end subroutine initArray
 
end program main

the output is right. So, when deallocation occurs, memory is released but the array shape is kept. Is it exact ? Any detailed explanation would be appreciated.

I read different posts on the subject (Can I use allocatable array as an intent(out) matrix in Fortran?, What is the effect of passing an allocatable variable into a subroutine with non-allocatable argument?, ...). So I understand that the array is deallocated but I would like to understand what does it mean because in my code, the size is kept and I am also surprised that this code works.

francescalus
  • 30,576
  • 16
  • 61
  • 96
Stef1611
  • 1,978
  • 2
  • 11
  • 30

2 Answers2

6

You are slightly misunderstanding what happens here.

Arrays which are deallocated on entry to a procedure with intent(out) are those allocatable arrays which correspond to an allocatable dummy.

What intent(out) means for an argument depends entirely on the characteristics of the dummy not actual argument.

Allocatable actual arguments which correspond to ordinary dummy arguments are not deallocated. (If they were, the dummy argument which is not allocatable would have to be not allocated!)

Instead, the allocation status of the actual argument remains unchanged and the shape of the assumed (not deferred) shape dummy argument remains the same.

The dummy argument becomes undefined, as an intent(out). For the ordinary dummy argument here, that refers simply to its value (which is immediately defined in that assignment statement).

francescalus
  • 30,576
  • 16
  • 61
  • 96
3

The deallocation happens when the dummy argument is allocatable and intent(out). Try

real, dimension(:), intent(out), allocatable :: myArray

to achieve that.

The fact that the actual argument in the main program is allocatable is immaterial to a subroutine without an allocatable dummy argument (such as yours).

I strongly suggest to name the array in the main program and the argument in the subroutine differently to better see the difference.

program main

 real, dimension(:), allocatable :: mainArray
 integer :: L=8

 allocate(mainArray(1:L))
 call initArray(mainArray)
 print *, mainArray
 
contains

 subroutine initArray(argArray)
 real, dimension(:), intent(out) :: argArray

 argArray(:) = 10.0
 
 end subroutine initArray
 
end program main

Now, mainArray is the actual argument, argArray is the dummy argument. The dummy argument must be allocatable for deallocation to happen.