Scoping rules for variable and functions in contained subroutines

左心房为你撑大大i 提交于 2019-11-28 11:33:49

问题


I have a problem understanding why a variable (i) declared in a subroutine is seen in a contained subroutine, but that this is not true for a function (fie) which results in a compilation error. I searched for an answer and also tried to see if I could find something in the Fortran 95 standard but in vain.

I wrote a small example program:

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

When compiling this with gfortran under cygwin (gfortran 5.4.0) I get the following error message:

$ gfortran aa.f90
aa.f90:20:15:

     x = x + fie(i)
               1
Error: ‘fie’ at (1) is not a function

When enabling either of the commented lines the program compiles and runs correctly.

I saw a similar error message when using the Intel compiler (Intel Fortran 12.1.7.367, indeed quite old).

It looks like fie has to be made available either in the contained routine or has to be used in the encompassing subroutine, but as said I could not find an answer on the net or in the Fortran 95 standard (or maybe I didn't look for the right words).

Any explanation?


回答1:


The simplest fix is to use

double precision, external :: fie

the external attribute (also can be specified by the external statement) says: this is a procedure, I am not declaring a local variable.

For the declaration without the external to be interpreted as a function declaration the function reference must be present within the function body. Internal functions don't count. And therefore the compiler created a local double precision variable called fie.

Thank's to IanH for the relevant standard rule (from Fortran 2008 (16.5.1.4p5), but Fortran 95 will have an equivalent):

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.

Of course explicit interfaces (best using modules) are much better than external functions.



来源:https://stackoverflow.com/questions/40696534/scoping-rules-for-variable-and-functions-in-contained-subroutines

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