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.