Reputation: 366
I am working on a project (which is due tomorrow :/) and encountered a problem when I tried to use a simplex algorithm on a function I wrote myself. It didn't work, and after now 5 hours of searching and experimenting, I found out the following:
When I pass a function to a subroutine, this function can't have any array arguments. Is this true? Because in the code that I am supposed to use it evidently SHOULD work.
I am using the ifort compiler. See below for a minimum example, which I basicaly took from http://malayamaarutham.blogspot.de/2006/02/passing-function-names-as-arguments-in.html
! Author : Kamaraju S Kusumanchi
! Email : [email protected]
! Last edited : Sun Feb 5 2006
!
! Sample program demonstrating the use of external attribute. This program
! shows how to pass function names as arguments in Fortran 90 programs.
!
! Compilation and execution steps
! $gfortran passing_functions.f90 -o passing_functions
! $./passing_functions
! beta = 5.500000
! beta = 1.500000
!
! I would appreciate any comments, feedback, criticism, mistakes, errors etc.,
! (however minor they are)
!
module dummy
implicit none
contains
!------------------------------------------------------------------------------
function func1(a)
implicit none
real :: a
real :: func1
func1 = a+5
end function func1
!------------------------------------------------------------------------------
function func2(b)
implicit none
real :: b(:)
real :: func2
func2 = b(1)
end function func2
!------------------------------------------------------------------------------
function func3(dyn_func, c)
implicit none
real :: c
real, external :: dyn_func
real :: func3
func3 = dyn_func(c)
end function func3
!------------------------------------------------------------------------------
function func4(dyn_func, c)
implicit none
real :: c(*)
real, external :: dyn_func
real :: func4
func4 = dyn_func(c)
end function func4
end module dummy
!------------------------------------------------------------------------------
program passing_functions
use dummy
implicit none
real :: alpha=0.5, beta
real :: gamma(2) = (/10,20/)
beta = func3(func1, alpha)
write(*,*) 'beta = ', beta
beta = func4(func2, gamma)
write(*,*) 'beta = ', beta
end program passing_functions
This is the output:
zeus$ passing.out
beta = 5.500000
forrtl: severe (174): SIGSEGV, segmentation fault occurred
Image PC Routine Line Source
passing.out 0000000000402D44 Unknown Unknown Unknown
passing.out 0000000000402C7C Unknown Unknown Unknown
libc.so.6 00002AFF7915D23D Unknown Unknown Unknown
passing.out 0000000000402B79 Unknown Unknown Unknown
zeus$
Upvotes: 1
Views: 3016
Reputation: 29391
The other answer could be used to solve your problem, but there are simpler ways without using pointers.
There is almost never a reason to use external
in modern Fortran. In Fortran questions that I see on Stackoverflow it almost always leads people to a wrong approach. Unless you are really sure, don't use external
.
What you want to do is declare (i.e., describe) the function arguments in functions func3
and func4
with interface
blocks. Here is how to do it for func4
... you should be able to figure out func3
:
function func4(dyn_func, c)
implicit none
real, dimension (:) :: c
interface
function dyn_func (x)
real :: dyn_func
real, dimension (:) :: x
end function dyn_func
end interface
real :: func4
func4 = dyn_func(c)
end function func4
Upvotes: 5