I'm trying to understand the difference between abstract interfaces and "normal" interfaces. What makes an interface abstract? When is each one necessary?
Suppose the examples below
module abstract_type_mod
implicit none
type, abstract :: abstract_t
contains
procedure(abstract_foo), pass, deferred :: Foo
end type
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
end module
module concrete_type_mod
use abstract_type_mod
implicit none
type, extends ( abstract_t ) :: concrete_t
contains
procedure, pass :: Foo
end type
contains
subroutine Foo ( this, a, b )
implicit none
class(concrete_t), intent(in) :: this
real, intent(in) :: a
real, intent(out) :: b
b = 2 * a
end subroutine
end module
module ifaces_mod
implicit none
interface
subroutine foo_sub ( a, b )
implicit none
real, intent(in) :: a
real, intent(out) :: b
end subroutine
end interface
end module
module subs_mod
implicit none
contains
pure subroutine module_foo ( a, b )
implicit none
real, intent(in) :: a
real, intent(out) :: b
b = 2 * a
end subroutine
end module
program test
use ifaces_mod
use subs_mod
use concrete_type_mod
implicit none
type(concrete_t) :: concrete
procedure(foo_sub) :: external_sub
procedure(foo_sub), pointer :: foo_ptr
real :: b
foo_ptr => external_sub
call foo_ptr ( 0.0, b )
print*, b
foo_ptr => module_foo
call foo_ptr ( 1.0, b )
print*, b
call concrete%Foo ( 1.0, b )
print*, b
end program
pure subroutine external_sub ( a, b )
implicit none
real, intent(in) :: a
real, intent(out) :: b
b = a + 5
end subroutine
The output is
5.000000
2.000000
2.000000
I haven't used abstract interfaces here. At least I think I havent? I've been doing this for a while and I've never used the abstract "qualifier" on interfaces. It seems that I haven't found a case where using abstract interfaces is required.
Could someone enlighten me here?
PS: Compiler Intel Visual Fortran Composer XE 2013 SP1 Update 3.
Edit:
Quoting Metcalf, Reid and Cohen in Modern Fortran Explained:
In Fortran 95, to declare a dummy or external procedure with an explicit interface, one needs to use an interface block. This is fine for a single procedure, but is somewhat verbose for declaring several procedures that have the same interface (apart from the procedure names). Furthermore, in Fortran 2003, there are several situations where this becomes impossible (procedure pointer components or abstract-type bound procedures).
So, is my compiler in error for accepting the code below and also the one with abstract type above?
module ifaces_mod
implicit none
interface
subroutine foo_sub ( a, b )
implicit none
real, intent(in) :: a
real, intent(out) :: b
end subroutine
end interface
end module
module my_type_mod
use ifaces_mod
implicit none
type my_type_t
procedure(foo_sub), nopass, pointer :: Foo => null()
end type
end module
In both cases, I'd say that I actually have declared abstract interfaces without using the abstract keyword. I think my confusion has roots on the fact that the compiler is accepting code like this.