Passing an internal procedure as argument

早过忘川 提交于 2019-11-29 11:41:25

You could put this all in a module, and make a a global module variable. Make faux a module procedure. That way, it has access to a.

module ode_module
    double precision::a

    contains

    subroutine f(x,a,ans)
        implicit none
        double precision f,ans,y,tol,c(24),w(9)

        call dverk(1,faux,x,y,1.d0,tol,ind,c,1,w)

    end subroutine 

    subroutine faux(n,xx,yy,yprime)
       implicite none
       integer n
       double precision xx,yy(n),yprime(n)
       yprime(1) = (yy(1)+a)*xx
    end subroutine faux

end module

You can check here which compilers support this F2008 feature:

http://fortranwiki.org/fortran/show/Fortran+2008+status

On that page, search for "Internal procedure as an actual argument" .

Passing an internal procedure is allowed by Fortran 2008. It is not limited to module. You just have to make sure, that the containing procedure is still running. It is not possible to save the pointer and make a so called 'closure' known from LISP and many modern languages. In languages like Fortran or C the enclosing environment for future calls is not saved and pointers to internal functions become invalid.

The advantage of internal procedure over module procedure is that you can share the data without sharing it in the whole module.

It works well will reasonably old versions of GCC (gfortran), Intel Fortran and Cray Fortran (personally tested) and possibly others. I remember not being able to compile by PGI and Oracle Fortran. As shown by Daniel, it can be checked at http://fortranwiki.org/fortran/show/Fortran+2008+status (search Internal procedure as an actual argument). The most recent version of this table is periodically published in ACM SIGPLAN Fortran Forum.

There is some interesting info in this article http://software.intel.com/en-us/blogs/2009/09/02/doctor-fortran-in-think-thank-thunk/

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!