简体   繁体   English

Fortran - 显式接口

[英]Fortran - explicit interface

I'm very new to Fortran, and for my research I need to get a monster of a model running, so I am learning as I am going along.我对 Fortran 很陌生,为了我的研究,我需要让一个模型的怪物运行,所以我正在学习。 So I'm sorry if I ask a "stupid" question.所以如果我问一个“愚蠢”的问题,我很抱歉。 I'm trying to compile (Mac OSX, from the command line) and I've already managed to solve a few things, but now I've come across something I am not sure how to fix.我正在尝试编译(Mac OSX,从命令行)并且我已经设法解决了一些问题,但是现在我遇到了一些我不确定如何解决的问题。 I think I get the idea behind the error, but again, not sure how to fix.我想我明白了错误背后的想法,但同样,不知道如何解决。

The model is huge, so I will only post the code sections that I think are relevant (though I could be wrong).模型很大,所以我只会发布我认为相关的代码部分(尽管我可能是错的)。 I have a file with several subroutines, that starts with:我有一个包含多个子例程的文件,其开头为:

    !==========================================================================================!
!    This subroutine simply updates the budget variables.                                  !
!------------------------------------------------------------------------------------------!
subroutine update_budget(csite,lsl,ipaa,ipaz)

   use ed_state_vars, only : sitetype     ! ! structure
   implicit none

   !----- Arguments -----------------------------------------------------------------------!
   type(sitetype)  , target     :: csite
   integer         , intent(in) :: lsl
   integer         , intent(in) :: ipaa
   integer         , intent(in) :: ipaz
   !----- Local variables. ----------------------------------------------------------------!
   integer                      :: ipa
   !----- External functions. -------------------------------------------------------------!
   real            , external   :: compute_water_storage
   real            , external   :: compute_energy_storage
   real            , external   :: compute_co2_storage
   !---------------------------------------------------------------------------------------!


   do ipa=ipaa,ipaz
      !------------------------------------------------------------------------------------!
      !      Computing the storage terms for CO2, energy, and water budgets.               !
      !------------------------------------------------------------------------------------!
      csite%co2budget_initialstorage(ipa) = compute_co2_storage(csite,ipa)
      csite%wbudget_initialstorage(ipa)   = compute_water_storage(csite,lsl,ipa)
      csite%ebudget_initialstorage(ipa)   = compute_energy_storage(csite,lsl,ipa)
   end do

   return
end subroutine update_budget
!==========================================================================================!
!==========================================================================================!

I get error messages along the lines of我收到以下错误消息

budget_utils.f90:20.54: Budget_utils.f90:20.54:

real , external :: compute_co2_storage 1真实,外部::compute_co2_storage 1
Error: Dummy argument 'csite' of procedure 'compute_co2_storage' at (1) has an attribute that requires an explicit interface for this procedure错误:(1) 处的过程“compute_co2_storage”的虚拟参数“csite”具有需要此过程的显式接口的属性

(I get a bunch of them, but they are essentially all the same). (我得到了一堆,但它们基本上都是一样的)。 Now, looking at ed_state_vars.f90 (which is "used" in the subroutine), I find现在,查看 ed_state_vars.f90(在子程序中“使用”),我发现

!============================================================================!
!============================================================================!
  !---------------------------------------------------------------------------!  
  ! Site type:
  ! The following are the patch level arrays that populate the current site.
  !---------------------------------------------------------------------------!  

type sitetype


     integer :: npatches

     !  The global index of the first cohort in all patches
     integer,pointer,dimension(:) :: paco_id

     ! The number of cohorts in each patch
     integer,pointer,dimension(:) :: paco_n

     ! Global index of the first patch in this vector, across all patches
     ! on the grid

     integer :: paglob_id

     ! The patches containing the cohort arrays
     type(patchtype),pointer,dimension(:) :: patch

Etc etc - this goes one for another 500 lines or so.等等等等 - 这是另外 500 行左右。 So to get to the point, it seems like the original subroutine needs an explicit interface for its procedures in order to be able to use the (dummy) argument csite.所以说到点子上,似乎原始子例程需要一个显式接口用于其过程,以便能够使用(虚拟)参数 csite。 Again, I am SO NEW to Fortran, but I am really trying to understand how it "thinks".再说一次,我对 Fortran 很陌生,但我真的很想了解它是如何“思考”的。 I have been searching what it means to have an explicit interface, when (and how!) to use it etc. But I can't figure out how it applies in my case.我一直在寻找拥有显式接口意味着什么,何时(以及如何!)使用它等。但我无法弄清楚它如何适用于我的情况。 Should I maybe use a different compiler (Intel?).我应该使用不同的编译器(英特尔?)。 Any hints?任何提示?

Edit: So csite is declared a target in all procedures and from the declaration type(site type) contains a whole bunch of pointer s, as specified in sitetype .编辑:因此csite在所有过程中都被声明为target ,并且声明type(site type)包含一大堆pointer ,如sitetype所指定。 But sitetype is being properly use d from another module ( ed_state_vars.f90 ) in all procedures.sitetype被正确地use其他模块(D ed_state_vars.f90中的所有过程)。 So I am still confused why it gives me the explicit interface error?所以我仍然很困惑为什么它给了我显式接口错误?

"explicit interface" means that the interface to the procedure (subroutine or function) is declared to the compiler. “显式接口”是指向编译器声明过程(子例程或函数)的接口。 This allows the compiler to check consistency of arguments between calls to the procedure and the actual procedure.这允许编译器检查对过程和实际过程的调用之间参数的一致性。 This can find a lot of programmer mistakes.这样可以发现很多程序员的错误。 You can do this writing out the interface with an interface statement but there is a far easier method: place the procedure into a module and use that module from any other entity that calls it -- from the main program or any procedure that is itself not in the module.您可以使用interface语句写出接口,但有一种更简单的方法:将过程放入模块中,并从调用它的任何其他实体use该模块——从主程序或任何本身不是的过程在模块中。 But you don't use a procedure from another procedure in the same module -- they are automatically known to each other.但是您不会use来自同一模块中另一个过程的过程——它们自动相互认识。

Placing a procedure into a module automatically makes its interface known to the compiler and available for cross-checking when it is use ed.放置过程到模块自动使其接口编译器知道的和可用于交叉检查时,它是useThis is easier and less prone to mistakes than writing an interface.这比编写接口更容易,也更不容易出错。 With an interface, you have to duplicate the procedure argument list.对于接口,您必须复制过程参数列表。 Then if you revise the procedure, you also have to revise the calls (of course!) but also the interface.然后如果你修改程序,你还必须修改调用(当然!)还有接口。

An explicit interface ( interface statement or module) is required when you use "advanced" arguments.使用“高级”参数时需要显式接口( interface语句或模块)。 Otherwise the compiler doesn't know to generate the correct call否则编译器不知道生成正确的调用

If you have a procedure that is use ed, you shouldn't describe it with external .如果您有一个use ed 的过程,则不应使用external描述它。 There are very few uses of external in modern Fortran -- so, remove the external attributes, put all of your procedures into a module, and use them.在现代 Fortran 中很少使用external —— 因此,删除external属性,将所有过程放入一个模块中,然后use它们。

I ran into the same problems you encountered whilst I was trying to install ED2 on my mac 10.9.我在尝试在 Mac 10.9 上安装 ED2 时遇到了与您相同的问题。 I fixed it by including all the subroutines in that file in a module, that is:我通过在模块中包含该文件中的所有子例程来修复它,即:

module mymodule
contains
subroutine update_budget(csite,lsl,ipaa,ipaz)
other subroutines ecc.
end module mymodule

The same thing had to be done to some 10 to 15 other files in the package.必须对包中的其他 10 到 15 个文件执行相同的操作。 I have compiled all the files and produced the corresponding object files but now I am getting errors about undefined symbols.我已经编译了所有文件并生成了相应的目标文件,但现在我收到有关未定义符号的错误。 However I suspect these are independent of the modifications so if someone has the patience this might be a way to solve at least the interface problem.但是我怀疑这些与修改无关,所以如果有人有耐心,这可能是一种至少解决界面问题的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM