fortran - 包含的子例程中变量和函数的作用域规则

标签 fortran fortran95

我无法理解为什么在子例程中声明的变量 (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/

相关文章:

Fortran 90/95 中的函数接口(interface)

fortran - Fortran 90 和 Fortran 95 之间的区别

Fortran90 valgrind 输出帮助。代码执行开始时发生无法解释的错误

fortran - 将实数写入字符串时输出为 '*'

c - 从列专业转移到行专业

boolean - 有没有理由写.eqv。 。真的。?

fortran - 如何在 fortran 90/95 中使用内部类型进行一些通用编程

compiler-errors - 使用读取语句时出错

c++ - 将 C++ 程序与 Fortran 库链接时对 _rpoly_ 的 undefined reference

linux - 在 Fortran 程序意外结束时刷新文件