Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Procedure with assumed-shape dummy argument must have an explicit interface [duplicate]

I am completely new to Fortran 90 and I am trying to understand how to pass an array to a function. I looked on the web and I could not find any clear and simple enough example, so I decided to post here.

I would like the function be able to work on an array of any length (the length of the array should not be one of the parameters of the functions).

I tried to write a simple example of a function that returns the sum of the elements of an array:

function mysum(arr)
    implicit none
    real, dimension(:), intent(in) :: arr
    real :: mysum
    integer :: i,arrsize
    arrsize = size(arr)
    mysum=0.0
    do i=1,arrsize
        mysum=mysum+arr(i)
    enddo
end function mysum

program test
    implicit none
    real, dimension(4) :: a
    real :: mysum,a_sum
    call random_number(a)
    print *,a
    a_sum=mysum(a)
    print *,a_sum
end program

When I try to compile, I get the following error:

array_test.f90:17.14:

 real mysum,a_sum
           1
Error: Procedure 'mysum' at (1) with assumed-shape dummy argument 'arr' must have an explicit interface

What is the problem with my program?

like image 239
valerio Avatar asked Mar 13 '17 14:03

valerio


1 Answers

Assumed shape dummy arguments (those with (:)) require explicit interface to the procedure to be available at the call site. That means the calling code must know how exactly the subroutine header looks like. See also Module calling an external procedure with implicit interface

That explicit interface can be provided in several ways

1. preferred - a module procedure

module procedures
  implicit none

contains

  function mysum(arr)

    real, dimension(:), intent(in) :: arr
    real :: mysum
    integer :: i,arrsize
    arrsize = size(arr)
    mysum=0.0
    do i=1,arrsize
        mysum=mysum+arr(i)
    enddo
  end function mysum
end module

program test
    use procedures

    implicit none
    !no mysum declared here, it comes from the module
    ...
end program

2. internal procedure - only for short simple procedures or if the procedure needs access to the host's variables. Because of the access to the host variables it is error-prone.

program test
    implicit none
    !no a_sum declared here, it is visible below contains
    ...    
contains

  function mysum(arr)

    !implicit none inherited from the program

    real, dimension(:), intent(in) :: arr
    real :: mysum
    integer :: i,arrsize
    arrsize = size(arr)
    mysum=0.0
    do i=1,arrsize
        mysum=mysum+arr(i)
    enddo
  end function mysum
end program

3. interface block - not recommended at all, you should have some particular reason to use it

function mysum(arr)
  ! removed to save space
end function mysum

program test
    implicit none

     interface
       function mysum(arr)
         real, dimension(:), intent(in) :: arr
         real :: mysum
       end function
     end interface

     !no mysum declared there
     !it is declared in the interface block
     ...
end program
like image 138
Vladimir F Героям слава Avatar answered Nov 02 '22 23:11

Vladimir F Героям слава