Difference between Fortran’s “abstract” and “normal” interfaces

The “normal” interfaces — known by the standard as specific interface blocks (as you use in the title of the question) — are just normal interface blocks for some procedure. Therefore:

interface
  subroutine foo_sub
  end subroutine
end interface

means that there exists an actual (external) subroutine named foo_sub and it conforms to the specified interface.

An abstract interface

abstract interface
  subroutine foo_sub_abs
  end subroutine
end interface

just specifies how some procedure may look like, but the name is the name of the interface, not of any actual procedure. It can be used for a procedure pointers

procedure(foo_sub_abs), pointer :: p

or for a dummy arguments

subroutine bar(f)
  procedure(foo_sub_abs) :: f

and it means that the actual procedure to which p will point or which is passed as f conforms to the abstract interface.

Note that you are allowed to use some existing procedure instead of an abstract interface in both two former examples. It just needs to have explicit interface available in the scope (typically it is in the same module, or in a module which is used).


As far as I know (but see @IanH’s comment below) the compiler is allowed to refuse your code:

  interface
    subroutine abstract_foo ( this, a, b )
      import :: abstract_t
      implicit none
      class(abstract_t), intent(in)  :: this
      real,              intent(in)  :: a
      real,              intent(out) :: b
    end subroutine
  end interface

because there exists no actual procedure named abstract_foo. Some compilers do not diagnose this, but they could.


Quite unrelated are generic interfaces. You can recognize them, because there is a name of a generic procedure after the word interface

  interface generic_sub
    procedure sub1

    subroutine sub2(...)
    end subroutine
  end interface

Here sub1 and sub2 both exist, sub1 is already known and has already explicit interface available, sub2 is external and looks as the interface specifies, and both are specific procedure of the generic generic_sub. This is quite a different usage.

You then call

call generic_sub(...)

and according to the arguments you pass, the compiler chooses which specific procedure is called, if it is sub1, or sub2.

I would stress that these can be split into sparate interface blocks with the same name declared at different locations. You can add a specific procedure into an existing generic procedure this way.

Leave a Comment