Search code examples
fortrangfortransubroutine

How to use allocatable arrays in Fortran subroutines?


Let me just preface this by saying that I am very new to Fortran but familiar with Python. My research project however requires me to use some pre-written Fortran code, which at this moment wont compile on my pc. I am trying to understand why.

The actual code I am trying to compile is very long and probably not very illuminating, but I think I have managed to come up with a minimal example of where I think the issue is. Let's say I have a very simple module and subroutine as follows,

module arraycheck
    implicit none
    real*8, allocatable, dimension(:) :: x
    contains
    subroutine fillx
        real*8, allocatable, dimension(:) :: x
        allocate(x(5))
        x(1) = 1
        x(2) = 2
        x(3) = 3
        x(4) = 4
        x(5) = 5
        print*, x
    end subroutine fillx
end module arraycheck

which I expect to simply create an array x, which when the subroutine fillx is called fills the array with the integers 1 to 5. My actual source contains something conceptually similar to this. Now I also have a main program as follows,

program main
use arraycheck
print*, x
call fillx
print*,x
end

My idea here would be that on the first print statement the variable x is still unallocated, so print returns nothing, and then on the second print statement x has been filled, so it should return the filled array.

However on both print statements nothing is returned. Now in my original source code something similar happens, which causes runtime to throw an error that an unallocated array was passed somewhere as an actual argument, which should have been allocated. It seems like the exact same thing happens as in my small example here.

So my question is, is the behaviour that I observe in my example here expected? And if it is, how can I alter the code to make it work in the way that I would want it to? If I know this I might better understand why the actual source doesn't work.

Just in case it is relevant, I am using gfortran on ubuntu.

Thanks!


Solution

  • You have too different xs. They do not have anything in common. One a module array and one array local to the subroutine. When you allocate the local array in the subroutine, it does not do anything to the other array in the module.

    Also, you cannot print array that is not allocated. That is not standard conforming (undefined behaviour). Anything can happen. You should definitely enable all compiler checks when diagnosing problems. The compiler should complain about your code with those checks.

    Remove the local array declaration and avoid referencing unallocated variables. Module procedures have access to module variables through host association.

    module arraycheck
        implicit none
        real*8, allocatable, dimension(:) :: x
    
      contains
    
        subroutine fillx
    
            allocate(x(5))
            x(1) = 1
            x(2) = 2
            x(3) = 3
            x(4) = 4
            x(5) = 5
            print*, x
        end subroutine fillx
    end module arraycheck
    
    
    program main
      use arraycheck
    
      call fillx
      print*,x
    end
    

    Also, real*8 is not standard Fortran, it is a non-standard extension. Fortran 90 and later uses the kind system instead.