5

Consider the following subroutine

subroutine myProc(m,n,flag,X)
Integer, intent(in) :: m,n
logical, intent(in) :: flag
real(8), intent(out), allocatable :: X(:,:)

if (flag) then
  allocate(X(m,n))
  ! some more code here
else 
  allocate(X(m-1,n))
  ! some more code here
end if
end subroutine myProc
!!!!!!!!!!!!!!!!!!!

Also, how do I call this procedure in a program? suppose I write

!... some code before
call myProc(5,6,.TRUE.,X)

Do I need to define X already as a (4,6) real array or pass an allocatable array to the subroutine?

Is doing all of that even possible in Fortran 95?

Pitt Prog
  • 161
  • 1
  • 4
  • 1
    Welcome. Please use tag [tag:fortran] for all Fortran questions. There is a difference between a matrix and an array. An array is a structured/indexed collection of elements of some type. A matrix is a mathematical structure from linear algebra which describes transformations between bases of vector spaces. Also note that `real(8)` is ugly, non portable and does not always mean 8 bytes or double precision. – Vladimir F Героям слава Jan 27 '18 at 07:48
  • Thank you for explaining me what a matrix is. Also it is kind of you to point out that real(8) is non-portable. About my actual question, both your suggestion and Dan's suggestions worked. Thank you. – Pitt Prog Jan 28 '18 at 14:54

2 Answers2

3

It is perfectly fine to pass an allocatable dummy argument to subroutine in Fortran 2003 and later. IIRC it was allowed by a TS (technical specification) to Fortran 95 first. All compilers support it today.

The actual argument does not have to be allocated when being passed to an allocatable dummy argument. Here it will actuully be automatically deallocated if it happens to be allocated, because the dummy is intent(out) and allocatable, intent(out) arguments are automatically deallocated when entering the subroutine.

Your code should work fine, but there is one important aspect, the subroutine must have an explicit interface. So it must be placed in a module. Or it must be internal (after contains) or an interface block must be used (ugly).

You can call it as you showed

call myProc(5,6,.TRUE.,X)

and X does not have to be allocated.

-4

You can put X in a module, declare it in the calling program and allocate it in the subroutine though. Any program, function, or subroutine that uses modules like this reference the same memory space so those variables are not even passed as arguments. It would look like this:

module Global
   real(8), allocatable :: X(:,:)
end module Global

program main
   use Global
   !... some code before
   call myProc(5,6,.TRUE.)
end program main

subroutine myProc(m,n,flag)
   use Global
   Integer, intent(in) :: m,n
   logical, intent(in) :: flag

   if (flag) then
     allocate(X(m,n))
     ! some more code here
   else 
     allocate(X(m-1,n))
     ! some more code here
   end if
end subroutine myProc
!!!!!!!!!!!!!!!!!!!
Dan Sp.
  • 1,419
  • 1
  • 14
  • 21
  • The fact, that it is not possible in Fortran 95 istechnically correct, given the OP asks for Fortran **95**, but misses the important points. The explanation is incorrect. The first two sentences are completely wrong. – Vladimir F Героям слава Jan 27 '18 at 07:52