【问题标题】:Intrinsic function as a function argument作为函数参数的内在函数
【发布时间】:2013-10-08 19:53:33
【问题描述】:

嗯,这就是我今天的问题......

我正在编写一个模块过程,它有一个作为参数的函数。这个模块看起来像这样:

module Integ
    implicit none
     <variables declaration>
contains
    function Integral(a,b,f) result(res)
        real, intent(in)     ::a, b
        real                 ::res

        interface
            pure function f(x)
                real, intent(in) :: x
                real             :: f
            endfunction
        endinterface


     <more code of function Integral>

    endfunction Integral

endmodule Integ

嗯,到这里为止,一切都很好。当我尝试将此函数与 Fortran 内在函数 一起使用时,会出现此问题。即,在此代码中:

program main

use Integ

implicit none

real   ::res,a,b

a=3.0; b=4.0

res=Integral(a,b,sin)  !<- This line does not work

!res=Integral(a,b,sen) !<- This line does work

contains
    function sen(x)
        real, intent(in)   :: x
        real               :: sen

        sen=sin(x)
    endfunction

endprogram

第一行不起作用,给出错误信息:

main.f90(17): error #6404: This name does not have a type, and must have an explicit type.   [SIN]
r=Int1DMonteCarlo(0.0,1.0,sin,10000)
--------------------------^

main.f90(17): error #6637: This actual argument must be the name of an external user function or the name of an intrinsic function.   [SIN]
r=Int1DMonteCarlo(0.0,1.0,sin,10000)
--------------------------^

但第二行(在小节中注释)确实如此。

这些错误让我很困惑,因为sin 是一个 Fortran 内在函数(与错误 nr 2 相矛盾的东西),因此在每个范围内都是显式的(与错误 nr 1 相矛盾的东西)。

显然我做错了什么,但我不知道是什么。

所以我想问一下:

  • 可以调用带有内部函数作为实际参数的模块过程吗?
  • 除了在过程中声明接口之外,我还失去了什么?

如果您有兴趣this is the complete source of the modulethis is the source of the main

对不起,如果我问了一个愚蠢的问题。我想我正在按照我现在正在阅读的书籍(Metcalf,Fortran V:II 的数值食谱)告诉我的方式做事。

感谢您的宝贵时间!

【问题讨论】:

    标签: fortran fortran90 argument-passing fortran95


    【解决方案1】:

    在主程序中使用intrinsic 语句来声明实际参数sin 是intrinsic。这个要求在 Fortran 标准的内在属性描述中有详细说明。

    着眼于未来,您最好围绕内在函数编写自己的包装函数 - 创建一个简单调用 sin 的函数 mysin。

    【讨论】:

    • 哦,你是对的!在模块过程中添加intrinsic :: sin 行并删除pure 属性解决了这个问题(第8.1.3 章梅特卡夫)。太好了!。
    • 所有 [标准] 内在函数都是纯函数,因此删除 PURE 对我来说似乎不合适。我会进一步调查。
    • 如果不删除pure,编译将中止并出现错误:main.f90(19): error #7892: Procedure argument must be PURE [SIN] r=Int1DMonteCarlo(0.0,1.0,sin,10000)
    • 我也看到了 - 但我不明白为什么。留意那些比我知识渊博的人here的回复。
    • Fortran 博士回答。看来我们发现了一个错误!