I am attempting to pass a generic procedure as an actual argument to a function:
module mymod
implicit none
interface func
module procedure :: func1
module procedure :: func2
endinterface func
contains
real function func1(x)
real,intent(in) :: x
func1 = 2*x
endfunction func1
real function func2(x,y)
real,intent(in) :: x
real,intent(in) :: y
func2 = 2*x + 3*y
endfunction func2
real function func3(func,x,y)
interface
real function func(x,y)
real,intent(in) :: x
real,intent(in) :: y
endfunction func
endinterface
real,intent(in) :: x
real,intent(in) :: y
func3 = func(x,y)
endfunction func3
endmodule mymod
program myprogram
use mymod
implicit none
write(*,*)func3(func,2.,3.)
endprogram myprogram
gfortran 6.2.0 notes that I cannot do this:
test.f90:43:16:
write(*,*)func3(func,2.,3.)
1
Error: GENERIC procedure ‘func’ is not allowed as an actual argument at (1)
Similarly, with ifort 17:
test.f90(39): error #8164: A generic interface name shall not be used as an actual argument. [FUNC]
write(*,*)func3(func,2.,3.)
----------------^
test.f90(39): error #6637: When a dummy argument is a function, the corresponding actual argument must also be a function. [FUNC]
write(*,*)func3(func,2.,3.)
----------------^
compilation aborted for test.f90 (code 1)
I am reading through the 2008 Standard section on generic interfaces and I cannot find such restriction. I also cannot think of a reason why the compiler would not be able to resolve the generic interface at compile-time. My gut is telling me that this should be doable, but I may not have the right approach. Do you know of a standard-compliant way to do this?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With