1

I am learning to program in fortran and was making a basic program. In it I am trying to return an array from a function in my program, which is resulting in this error: Interface mismatch in global procedure 'test1' at (1): Rank mismatch in function result (0/1).

Below is a reconstruction of the error:

program Test
    implicit none
    integer :: a
    interface
        function test1(n) result (m)
            integer :: n
        end function test1
    end interface

    a = test1(4)

end program Test

function test1(n) result (m)
    implicit none
    integer :: n, m(2)
    m(1) = n**2
end function test1

The error is after the interface statement at function test1(n) result (m).

Since I am new to fortran, I assume I have missed something basic so any help is appreciated.

blunty6363
  • 29
  • 6
  • See https://stackoverflow.com/questions/43768605/function-result-has-no-implicit-type/43769708#43769708 for some assistance. – High Performance Mark Mar 05 '22 at 15:53
  • @HighPerformanceMark Hi, I played around with some of the things it suggested in the question you linked but still didn't get it to work. – blunty6363 Mar 05 '22 at 16:19

1 Answers1

1

The interface and implementation of test1 have mismatched arguments, and a is mismatched to the result of test1. If you declare a to be an array of length 2 and add a declaration of m to your interface to also be an array of length 2, then everything should work:

program Test
   implicit none
   integer :: a(2)
   interface
       function test1(n) result (m)
           integer :: n, m(2)
       end function test1
   end interface

   a = test1(4)
   write(*,*) a

end program Test

function test1(n) result (m)
   implicit none
   integer :: n, m(2)
   m(1) = n**2
end function test1

Declaring functions

Declaring functions in the global scope and calling them through an interface will lead to a lot of excess code writing and maintenance. There are two better ways to declare functions; as internal functions, or in a module.

If you're writing a short program, you can get away with putting your functions directly inside your program, using contains. This gets rid of the need for an interface entirely:

program Test
   implicit none
   integer :: a(2)

   a = test1(4)
contains
   function test1(n) result (m)
      integer :: n, m(2)
      m(1) = n**2
   end function test1
end program Test

note that I've dropped the implicit none from the function, as it's now inherited from Test.

If your code gets a bit bigger, you will want to declare your functions in separate modules, as:

module test_module
   implicit none
contains
function test1(n) result (m)
   integer :: n, m(2)
   m(1) = n**2
end function test1
end module

program Test
   use test_module
   implicit none
   integer :: a(2)

   a = test1(4)
end program Test
veryreverie
  • 2,871
  • 2
  • 13
  • 26
  • Thank you very much for your response, the code does run. I see why you recommend this but for the sake of my program I am trying to use the functions externally, hence the interface statement with the empty function as I read online that when you declare the function externally, you should include the variables used in the function in an interface statement in the main program. Do you know how I could declare the function externally? Also what does `interface test1` do instead of just `interface`? – blunty6363 Mar 05 '22 at 16:46
  • Sorry, I didn't see the top of your post to start with due to the way the post showed when I clicked on the notification. That is fine then, I will research into modules on my own. But could you still explain the `interface test1` vs `interface`/`interface test1` in general? – blunty6363 Mar 05 '22 at 16:50
  • `interface foo ; procedure bar ; end interface` means you can call `bar` by the name `foo`. This is particularly useful if you have multiple procedures (e.g. `add_integer`, `add_real` etc.) which you want to call by the same name (e.g. `add`). The earlier edit of my answer used `interface test1` because I'd got myself confused, and was trying to write an interface to an internal procedure (which is not allowed without the re-name). – veryreverie Mar 05 '22 at 16:50
  • See [this question](https://stackoverflow.com/questions/35068442/difference-between-fortrans-abstract-and-normal-interfaces) for more details. – veryreverie Mar 05 '22 at 16:54
  • 2
    "to use the functions externally" Honestly, don't. Make your life easy - put all procedures in modules. It will pay huge dividends in the long run. External functions should barely have been used in 3 decades. – Ian Bush Mar 05 '22 at 20:11