I am attempting to pass a generic procedure as an actual argument to a function:
module mymod
implicit none
interface func
module procedure :: func1
mod
No, this is not allowed. Actually, you cannot even pass generic INTRINSIC functions as dummy arguments.
A standard compliant way is to use the right specific functions directly. With INTRINSIC functions you sometimes must write a wrapper for the right kind, when the specific doesn't have a standard name.
For example:
call integrate(derf,0.,1.)
contains
function derf(x)
real(dbl) :: derf
real(dbl), intent(in) :: x
derf = erf(x)
end function
end
is necessary if you want to pass the double precision real (or any other) version of erf()
because there is no specific function available.
The Fortran standard doesn't allow one to pass generic procedures as arguments. In order to pass intrinsic functions/subroutines one must resort to user-defined wrapper procedures.
module mymod
! Explicit typing only
implicit none
! Declare procedure interface
interface
function my_func(x, y) result (return_value)
real, intent(in) :: x, y
real :: return_value
end function my_func
end interface
contains
function func1(x) result (return_value)
real,intent(in) :: x
real :: return_value
return_value = 2*x
end function func1
function func2(x, y) result (return_value)
real, intent(in) :: x, y
real :: return_value
return_value = 2*x + 3*y
end function func2
function func3(user_defined_func, x, y) result (return_value)
procedure(my_func) :: user_defined_func
real, intent(in) :: x, y
real :: return_value
return_value = user_defined_func(x,y)
end function func3
end module mymod
program main
use ISO_Fortran_env, only: &
stdout => OUTPUT_UNIT, &
compiler_version, &
compiler_options
use mymod
! Explicit typing only
implicit none
write (stdout, *) func3(func2, 2.0, 3.0)
write (stdout, *) func3(foo, 2.0, 3.0)
write (stdout, *) func3(my_atan2, 2.0, 3.0)
print '(/4a/)', &
' This file was compiled using ', compiler_version(), &
' using the options ', compiler_options()
contains
! A user defined function
function foo(x, y) result (return_value)
real, intent(in) :: x, y
real :: return_value
return_value = 42
end function foo
! A wrapper function to invoke the intrinsic atan2
function my_atan2(x, y) result (return_value)
real, intent(in) :: x, y
real :: return_value
return_value = atan2(x,y)
end function my_atan2
end program main
yields
gfortran -std=f2008ts -o main.exe mymod.f90 main.f90
./main.exe
13.0000000
42.0000000
0.588002622
This file was compiled using GCC version 6.1.1 20160802 using the options -mtune=generic -march=x86-64 -std=f2008ts