Фортран - явный интерфейс

Я очень плохо знаком с Фортраном, и для моих исследований мне нужно запустить монстра модели, поэтому я учусь по ходу дела. Поэтому извините, если я задам "глупый" вопрос. Я пытаюсь скомпилировать (Mac OSX, из командной строки), и мне уже удалось решить несколько вещей, но теперь я столкнулся с чем-то, что я не уверен, как исправить. Я думаю, что я понял за ошибку, но опять же, не уверен, как исправить.

Модель огромна, поэтому я буду публиковать только те фрагменты кода, которые, на мой взгляд, актуальны (хотя я могу ошибаться). У меня есть файл с несколькими подпрограммами, который начинается с:

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

Я получаю сообщения об ошибках в соответствии с

budget_utils.f90:20,54:

реальный, внешний:: compute_co2_storage 1
Ошибка: фиктивный аргумент 'csite' процедуры 'compute_co2_storage' в (1) имеет атрибут, который требует явного интерфейса для этой процедуры

(Я получаю кучу их, но они по сути все одинаковые). Теперь, глядя на 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

И т.д. Итак, чтобы перейти к сути, похоже, что исходной подпрограмме нужен явный интерфейс для своих процедур, чтобы можно было использовать (фиктивный) аргумент csite. Опять же, я так нова для Фортрана, но я действительно пытаюсь понять, как он "думает". Я искал, что значит иметь явный интерфейс, когда (и как!) Его использовать и т. Д. Но я не могу понять, как это применимо в моем случае. Должен ли я использовать другой компилятор (Intel?). Есть намеки?

Редактировать: Итак csite объявлен target во всех процедурах и из декларации type(site type) содержит целую кучу pointers, как указано в sitetype, Но sitetype правильно used из другого модуля (ed_state_vars.f90) во всех процедурах. Так что я все еще в замешательстве, почему это дает мне явную ошибку интерфейса?

2 ответа

"явный интерфейс" означает, что интерфейс к процедуре (подпрограмма или функция) объявлен компилятору. Это позволяет компилятору проверять согласованность аргументов между вызовами процедуры и фактической процедурой. Это может найти много ошибок программиста. Вы можете сделать это, написав интерфейс с interface утверждение, но есть гораздо более простой метод: поместите процедуру в модуль и use этот модуль от любой другой сущности, которая его вызывает - от основной программы или любой процедуры, которая сама не находится в модуле. Но ты не use процедура из другой процедуры в том же модуле - они автоматически известны друг другу.

Размещение процедуры в модуле автоматически делает его интерфейс известным компилятору и доступным для перекрестной проверки, когда она useредактор Это проще и менее подвержено ошибкам, чем написание интерфейса. С интерфейсом вы должны продублировать список аргументов процедуры. Затем, если вы пересмотрите процедуру, вы также должны пересмотреть вызовы (конечно!), А также интерфейс.

Явный интерфейс (interface оператор или модуль) требуется при использовании "расширенных" аргументов. В противном случае компилятор не знает, чтобы сгенерировать правильный вызов

Если у вас есть процедура, которая useЭд, ты не должен описывать это external, Есть очень мало применений external в современном фортране - убери external атрибуты, поместите все ваши процедуры в модуль, и use их.

Я столкнулся с теми же проблемами, с которыми вы столкнулись, когда пытался установить ED2 на мой Mac 10.9. Я исправил это, включив все подпрограммы в этом файле в модуль, то есть:

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

То же самое нужно было сделать с 10-15 другими файлами в пакете. Я скомпилировал все файлы и создал соответствующие объектные файлы, но теперь я получаю ошибки о неопределенных символах. Однако я подозреваю, что они не зависят от модификаций, поэтому, если у кого-то есть терпение, это может быть способом решения по крайней мере проблемы с интерфейсом.

Другие вопросы по тегам