Mishter_Jingles
Mishter_Jingles

Reputation: 104

How to pass a function returning an array as an argument in FORTRAN

I have this function f, that returns an array, and this function f is given as an argument to a function g, example:

function f(a)
 real, dimension(2)::f
 real a
 f(1)=a
 f(2)=a+1
end function

function g(f)
 real, dimension(2)::f,g
 g=f(1.1)
end function

But at the line g=f(1.1) it goes wrong, fortran thinks 1.1 is the index of the array f instead of the value which f has to evaluate. The literal error is: ||Error: Legacy Extension: REAL array index | Can you help me?

Upvotes: 1

Views: 859

Answers (1)

Jonathan Dursi
Jonathan Dursi

Reputation: 50927

You can do this, but you have to explicitly define f in the g function as being a function which returns two reals, rather than an array 2 two reals. Admittedly, the convention that's used in fortran for describing the return type of a function makes that distinction less obvious than it should be.

The way you define something to be of type function is with an interface block; that interface block describes both the function's return type and its argument list. It basically just looks like the first few lines of the declaration of the function, with the body of the function deleted. (I'm saying "function" here, but really should be saying "subprograms"; it works the same way with subroutines). Then the compiler knows both what the return value of the function is, but also the argument list. An interface block is something like a function prototype in C-based languages.

Using an interface block for your argument looks like this:

module functions
implicit none

contains

    function f(a)
     real, dimension(2)::f
     real, intent(in) :: a
     f(1)=a
     f(2)=a+1
    end function

    function g(f)
     real, dimension(2)::g
     interface
        function f(x)
            real, dimension(2) :: f
            real, intent(in) :: x
        end function f
     end interface

     g=f(1.1)

    end function

end module functions

program test
    use functions
    implicit none

    real, dimension(2) :: result

    result = g(f)
    print *, 'result = ', result
end program test

And the results are as you'd expect:

$ gfortran -o interface_ex interface_ex.f90
$ ./interface_ex
 result =    1.1000000       2.0999999

Upvotes: 4

Related Questions