Fortran - 显式接口 [英] Fortran - explicit interface

查看:33
本文介绍了Fortran - 显式接口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对 Fortran 非常陌生,为了我的研究,我需要让一个模型的怪物运行,所以我正在学习.所以如果我问一个愚蠢"的问题,我很抱歉.我正在尝试编译(Mac OSX,从命令行)并且我已经设法解决了一些问题,但是现在我遇到了一些我不确定如何解决的问题.我想我明白了错误背后的想法,但同样不知道如何解决.

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. 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. 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:

真实的,外部的 :: compute_co2_storage1
错误:(1) 处的过程compute_co2_storage"的虚拟参数csite"具有需要此过程的显式接口的属性

real , external :: 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

(我得到了一堆,但它们基本上都是一样的).现在,查看 ed_state_vars.f90(在子程序中使用"),我发现

(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

!============================================================================!
!============================================================================!
  !---------------------------------------------------------------------------!  
  ! 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

等等 - 这会再写 500 行左右.因此,为了能够使用(虚拟)参数 csite,原始子例程似乎需要一个显式接口用于其过程.再说一次,我对 Fortran 很陌生,但我真的很想了解它是如何思考"的.我一直在寻找拥有显式接口的含义,何时(以及如何!)使用它等.但我无法弄清楚它如何适用于我的情况.我应该使用不同的编译器(英特尔?).有什么提示吗?

Etc etc - this goes one for another 500 lines or so. 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. Again, I am SO NEW to Fortran, but I am really trying to understand how it "thinks". 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?

所以 csite 在所有过程中被声明为 target 并且从声明 type(site type) 包含一大堆 pointers,如 sitetype 中所指定.但是 sitetype 在所有程序中都被正确地used 来自另一个模块 (ed_state_vars.f90).所以我仍然很困惑为什么它给了我显式接口错误?

So csite is declared a target in all procedures and from the declaration type(site type) contains a whole bunch of pointers, as specified in sitetype. But sitetype is being properly used from another module (ed_state_vars.f90) in all procedures. So I am still confused why it gives me the explicit interface error?

推荐答案

显式接口"是指向编译器声明过程(子程序或函数)的接口.这允许编译器检查对过程和实际过程的调用之间参数的一致性.这样可以发现很多程序员的错误.您可以使用 interface 语句来写出接口,但有一个更简单的方法:将过程放入一个模块中,然后从任何其他调用该模块的实体中use它——来自主程序或任何本身不在模块中的过程.但是您不会使用来自同一模块中另一个过程的过程——它们自动相互认识.

"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. But you don't use a procedure from another procedure in the same module -- they are automatically known to each other.

将过程放入模块会自动使其接口为编译器所知,并在使用时可用于交叉检查.这比编写接口更容易,也更不容易出错.对于接口,您必须复制过程参数列表.那么如果你修改程序,你也必须修改调用(当然!)还有接口.

Placing a procedure into a module automatically makes its interface known to the compiler and available for cross-checking when it is useed. This 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.

使用高级"参数时需要显式接口(interface 语句或模块).否则编译器不知道生成正确的调用

An explicit interface (interface statement or module) is required when you use "advanced" arguments. Otherwise the compiler doesn't know to generate the correct call

如果你有一个useed的过程,你不应该用external来描述它.在现代 Fortran 中很少使用 external —— 所以,删除 external 属性,把你的所有过程放到一个模块中,然后 use 他们.

If you have a procedure that is useed, you shouldn't describe it with 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 - 显式接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆