How can I introduce an allocatable array which allocate in subroutine?

I have some allocatable array which their size is determined in the subroutine. How can I introduce them in the main block which I lately not have any problems with it?

Symbolic code is:

Main PROG

IMPLICIT NONE

REAL, DIMENSION(:,:), ALLOCATABLE :: A
REAL, DIMENSION(:,:), ALLOCATABLE :: B
REAL, DIMENSION(:,:), ALLOCATABLE :: C

CALL SUB(A,B,C)

!Continue the program

END MAIN PROG
-------------------
SUB(A,B,C)

IMPLICIT NONE

REAL, DIMENSION(:,:) :: A
REAL, DIMENSION(:,:) :: B
REAL, DIMENSION(:,:) :: C

!OPERATION ON A AND B WHICH DETERMINE THE DIMENSION OF C

END SUB

I also try to allocate/deallocate and it doesn’t work.
Furthermore, I cant use the model structure.
Please explain your solution in detail.

You can take a look at https://www.fortran90.org/src/best-practices.html#allocatable-arrays

Any arrays that are allocated or deallocated in subroutine SUB (in your case array C) need to be declared ALLOCATABLE in that subroutine.

If I declared “allocatable”, the compiler shows error that: C is a dummy argument so can not be allocatable

If I declared “allocatable”, the compiler shows error that: C is a dummy argument so can not be allocatable

In another post you wrote,

I write my code in PLATO as a fortran95.

I think that is the Salford compiler. A feature of Fortran 2003 that was implemented in some but not all Fortran 95 compilers was that dummy arguments can be ALLOCATABLE. In strict Fortran 95 you can get similar functionality by declaring the dummy argument as a POINTER. But it would be better for you to “graduate” to a more modern compiler such as gfortran or Intel Fortran, which are both free. The version of gfortran I use is from equation.com I think most people here are using compilers that support at least the Fortran 2003 standard, if not F2008 or F2018.

1 Like

Hi @VOLCANIC_9, further to @Beliavsky’s explanation of modern compilers, be aware that functions and subroutines that aren’t placed in modules have limited functionality; in this case you cannot pass unallocated allocatable arrays to subroutines for allocation unless they are in a module or you specify the interface yourself.

The following two solutions should work with a modern Fortran compiler:

Subroutine in module (click to expand)
module routines
implicit none

contains

subroutine sub(A,B,C)

REAL, DIMENSION(:,:), allocatable, intent(out) :: A
REAL, DIMENSION(:,:), allocatable, intent(out) :: B
REAL, DIMENSION(:,:), allocatable, intent(out) :: C

allocate(A(10,10))
allocate(B(20,20))
allocate(C(30,30))

end subroutine sub

end module routines

program PROG
use routines
implicit none

REAL, DIMENSION(:,:), ALLOCATABLE :: A
REAL, DIMENSION(:,:), ALLOCATABLE :: B
REAL, DIMENSION(:,:), ALLOCATABLE :: C

CALL SUB(A,B,C)

write(*,*) size(A,1), ',', size(A,2)
write(*,*) size(B,1), ',', size(B,2)
write(*,*) size(C,1), ',', size(C,2)

END program PROG
Explicit subroutine interface (click to expand)
program PROG

implicit none

interface
  subroutine sub(A,B,C)
        REAL, DIMENSION(:,:), allocatable, intent(out) :: A
        REAL, DIMENSION(:,:), allocatable, intent(out) :: B
        REAL, DIMENSION(:,:), allocatable, intent(out) :: C
    end subroutine sub
end interface

REAL, DIMENSION(:,:), ALLOCATABLE :: A
REAL, DIMENSION(:,:), ALLOCATABLE :: B
REAL, DIMENSION(:,:), ALLOCATABLE :: C

CALL SUB(A,B,C)

write(*,*) size(A,1), ',', size(A,2)
write(*,*) size(B,1), ',', size(B,2)
write(*,*) size(C,1), ',', size(C,2)

END program PROG

subroutine sub(A,B,C)

REAL, DIMENSION(:,:), allocatable, intent(out) :: A
REAL, DIMENSION(:,:), allocatable, intent(out) :: B
REAL, DIMENSION(:,:), allocatable, intent(out) :: C

allocate(A(10,10))
allocate(B(20,20))
allocate(C(30,30))

end subroutine sub
2 Likes