11

私は Fortran に非常に慣れていません。私の研究では、モデルのモンスターを実行する必要があるため、作業を進めながら学習しています。なので、「バカみたい」な質問ですみません。コンパイルしようとしています (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:

real , external :: compute_co2_storage 1
エラー: (1) のプロシージャ 'compute_co2_storage' のダミー引数 'csite' には、このプロシージャの明示的なインターフェイスを必要とする属性があります

(私はそれらをたくさん手に入れましたが、本質的にはすべて同じです)。さて、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

などなど - これは、さらに 500 行ほどになります。要するに、元のサブルーチンは、(ダミーの) 引数 csite を使用できるようにするために、そのプロシージャ用の明示的なインターフェイスが必要なようです。繰り返しますが、私は Fortran を初めて使用しますが、Fortran がどのように「考える」かを本当に理解しようとしています。明示的なインターフェイスを持つことの意味、いつ (そしてどのように!) 使用するかなどを検索してきましたが、私の場合にどのように適用されるかわかりません。別のコンパイラ (Intel?) を使用する必要があるかもしれません。ヒントはありますか?

編集:すべてのプロシージャでcsitea が宣言され、宣言からで指定されているように、一連の sが含まれています。しかし、すべての手順で別のモジュール ( ) から適切にd されています。だから、なぜ明示的なインターフェースエラーが発生するのか、まだ混乱していますか?targettype(site type)pointersitetypesitetypeuseed_state_vars.f90

4

2 に答える 2

20

「明示的なインターフェイス」とは、プロシージャ (サブルーチンまたは関数) へのインターフェイスがコンパイラに対して宣言されていることを意味します。これにより、コンパイラーは、プロシージャーへの呼び出しと実際のプロシージャーとの間の引数の整合性をチェックできます。これにより、多くのプログラマーの間違いを見つけることができます。ステートメントを使用してインターフェースを書き出すこともできますinterfaceが、はるかに簡単な方法があります。プロシージャーをモジュールに配置し、useそのモジュールをそれを呼び出す他のエンティティー (メイン・プログラムまたはそれ自体が含まれていないプロシージャー) から配置します。モジュール。ただし、同じモジュール内の別のプロシージャからのプロシージャではありませんuse。それらは自動的に相互に認識されます。

useプロシージャをモジュールに配置すると、自動的にそのインターフェイスがコンパイラに認識され、 ed時にクロスチェックできるようになります。これは、インターフェイスを記述するよりも簡単で、間違いを起こしにくくなります。インターフェイスでは、プロシージャの引数リストを複製する必要があります。次に、手順を修正する場合は、呼び出しも修正する必要があります (もちろん!) だけでなく、インターフェイスも修正する必要があります。

interface「高度な」引数を使用する場合は、明示的なインターフェイス (ステートメントまたはモジュール) が必要です。そうしないと、コンパイラは正しい呼び出しを生成することを知りません

useedの手順がある場合は、 で記述しないでくださいexternalexternal現代の Fortranでは の使用はほとんどありません。そのため、external属性を削除し、すべてのプロシージャをモジュールに入れuseます。

于 2013-05-10T23:58:04.157 に答える