我有一个问题,理解为什么在子例程中声明的变量(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标准中找到答案(或者我没有找到合适的词语。)
有任何解释吗?
答案 0 :(得分:2)
最简单的解决方法是使用
double precision, external :: fie
外部属性(也可以由external
语句指定)说:这是一个过程,我没有声明一个局部变量。
对于不将external
解释为函数声明的声明,函数体必须存在函数引用。内部功能不算数。因此编译器创建了一个名为fie
的本地双精度变量。
感谢IanH的相关标准规则(来自Fortran 2008(16.5.1.4p5),但Fortran 95将具有相同的标准):
如果带有隐式接口的外部或虚拟过程是 通过主机关联访问,然后它应具有外部 主机范围单元中的属性;如果它作为函数调用 内部范围单元,其类型和类型参数应为 在主机范围内建立。的类型和类型参数 在作用域中建立具有EXTERNAL属性的函数 如果该作用域单元显式声明它们,则调用 功能,从模块访问功能,或访问 函数来自其主机的类型和类型参数 建立的。
当然,显式接口(最好使用模块)比外部函数好得多。