Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Throwing an error if any procedure interface is not explicitly defined, or in a module in Fortran 90+

In the article Mistakes in Fortran 90 Programs That Might Surprise You

There is this following section,

Danger of calling Fortran 90 style routines

      program main
      real, dimension(5) :: x

      x = 0.
! THIS IS WRONG
      call incb(x)
      print *, x

      end program main

      subroutine incb(a)
! this is a fortran90 style subroutine
      real, dimension(:) :: a
      a = a + 1.
      end subroutine incb

Explanation The subroutine incb uses a Fortran 90 style assumed shape array (containing dimension(:)). Such routines must either be in a module, or have an explicit interface wherever they are used. In this example, neither one was true.

One correct way to call such procedures is to use an explicit interface as follows:

      program main
      real, dimension(5) :: x

! THIS IS THE RIGHT WAY
      interface
         subroutine incb(a)
           real, dimension(:) :: a
         end subroutine incb
      end interface

      x = 0.
      call incb(x)
      print *, x

      end program main

      subroutine incb(a)
! this is a fortran90 style subroutine
      real, dimension(:) :: a
      a = a + 1.
      end subroutine incb

If the routine is in a module interfaces are generated automatically and do not need to be explicitly written.

! THIS IS ANOTHER RIGHT WAY
      module inc
      contains
      subroutine incb(a)
! this is a fortran90 style subroutine
      real, dimension(:) :: a
      a = a + 1.
      end subroutine incb
      end module inc

      program main
      use inc
      real, dimension(5) :: x

      x = 0.
      call incb(x)
      print *, x

      end program main

If interfaces are used, the interface MUST match the actual function.

So continuing my question, is there an option in gfortran or other compilers to prevent compilation if there is a call to a procedure whose interface is not explicity defined (or defined in a module)?

If not, shouldn't it be a feature?

like image 873
osolmaz Avatar asked May 26 '14 15:05

osolmaz


1 Answers

For gfortran there is the compile option -Wimplicit-interface:

-Wimplicit-procedure
Warn if a procedure is called that has neither an explicit interface nor has been declared as EXTERNAL.

This can be coupled with -Werror to treat this as an error.

On compiling this (with gfortran 4.8.2)

  call heffalump(1)
end

one sees

call heffalump(1)
1
Warning: Procedure 'heffalump' called with an implicit interface at (1)

Do note, however, that although this can be a useful test for "silly mistakes" in newly developed modern code, things can be quite correct and still fail this test. See also Vladimir F's comment to this answer.

Of course, a compiler in most circumstances can't tell whether the procedure requires an explicit interface. See this answer for options to allow the compiler to do a little extra work in that regard.

like image 54
francescalus Avatar answered Sep 29 '22 12:09

francescalus