我无法理解为什么在子例程中声明的变量 (i
) 出现在包含的子例程中,但对于函数 (fie
) 这会导致编译错误。我寻找答案,并试图看看是否可以在 Fortran 95 标准中找到一些东西,但没有成功。
我写了一个小示例程序:
program pgm
call a
end
subroutine a
implicit none
integer :: i
double precision :: fie
i = 7
call b
!write(*,*) fie(9)
contains
subroutine b
double precision :: x
!double precision :: fie
x = i
x = x + fie(i)
write(*,*) x
end subroutine
end subroutine
double precision function fie(ii)
implicit none
integer, intent(in) :: ii
fie = ii
end function
在 cygwin (gfortran 5.4.0) 下使用 gfortran 编译此文件时,我收到以下错误消息:
$ gfortran aa.f90
aa.f90:20:15:
x = x + fie(i)
1
Error: ‘fie’ at (1) is not a function
启用任一注释行时,程序都会正确编译并运行。
我在使用英特尔编译器时看到了类似的错误消息(英特尔 Fortran 12.1.7.367,确实很旧)。
看起来 fie
必须在包含的例程中可用,或者必须在包含的子例程中使用,但正如我所说,我在网上或 Fortran 中找不到答案95标准(或者也许我没有寻找合适的词)。
有什么解释吗?
最佳答案
最简单的修复方法是使用
double precision, external :: fie
外部属性(也可以由external
语句指定)表示:这是一个过程,我没有声明局部变量。
为了将不带 external
的声明解释为函数声明,函数引用必须存在于函数体内。内部函数不算在内。因此编译器创建了一个名为 fie
的局部 double 变量。
感谢 IanH 提供的相关标准规则(来自 Fortran 2008 (16.5.1.4p5),但 Fortran 95 将有等效规则):
If an external or dummy procedure with an implicit interface is accessed via host association, then it shall have the EXTERNAL attribute in the host scoping unit; if it is invoked as a function in the inner scoping unit, its type and type parameters shall be established in the host scoping unit. The type and type parameters of a function with the EXTERNAL attribute are established in a scoping unit if that scoping unit explicitly declares them, invokes the function, accesses the function from a module, or accesses the function from its host where its type and type parameters are established.
当然,显式接口(interface)(最好使用模块)比外部函数要好得多。
关于fortran - 包含的子例程中变量和函数的作用域规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40696534/