標準コーディングルール

2001年9月1日版


目次

1.はじめに
2.スタイルルール(推奨リスト)
3.Fortran90 の機能を生かして
4.禁止事項
5.現段階では規定していないが重要なもの
付録 気象予報モデル・データ同化プログラムのためのコメント
参考文献・参考URL
変更履歴


1.はじめに

 ヨーロッパや米国の気象機関では、プログラムのソースコードを理解しやすく管理しやすいものにし、またソースコードの交換を容易にするため、プログラミングルールが作成されている。日本でもこれらを参考にして、気象庁数値予報課と気象研究所気候研究部・予報研究部が中心となって日本版標準コーディングルールを作成している。その目的は、プログラミング・スタイルを統一することにより、可読性と移植性を高め、維持管理を容易にすることである。この目的に賛同する開発担当者は、このルールに従いプログラムを作成し、同時にこのルールを改善するよう努力してほしい。(本ルールを守らなければ気象庁の業務プログラムとして登録されない、などということはありません。)

 このプログラミングルールではFortran 90 の使用を前提としている。Fortran 90 は、 FORTRAN 77 と互換性を保ちながら様々な機能を付加したもので、従来と比較して多くの点で改良されている。最新の JIS 規格は Fortran 95 であるが、Fortran 90 しか使えない環境が依然多い状況であると思われるので、Fortran 95 の新機能は当面使わないことを推奨する。

 対象とするプログラムとして、気象予報モデルとデータ同化モデルを想定してはいるが、高速で実行する必要がある大規模プログラムを多人数で共同開発する場合には、異分野でも役に立つと考えている。

 一部のルールについては断定的に記述していない部分がある。今後 Fortran 90 についてより多くの経験をつむことにより、今後の改訂版では追加・削除・変更されることを了解していただきたい。

2.スタイルルール(推奨リスト)

並列最適化コンパイラの動作を助け、バグを少なくするため、配列代入文の上下限指定は省略しないほうがよい。

3.Fortran90 の機能を生かして

3.1 モジュールの使い方

3.1.1 モジュールの3つの使用方法

 モジュールは Fortran90の新しい機能のうち、最も重要な機能の1つである。しかし、これを乱用すると分かりにくいプログラムになってしまう。(例えば、モジュールの共有変数の値は、そのモジュール外のいろいろなサブルーチンから自由に変更可能であるが、その自由を認めると、その共有変数がどこでどういうタイミングで変更されるのか理解が難しいプログラムになってしまう。)
 そこで、プログラムを分かりやすいものにするため、モジュールの使用方法を以下の3つの類型に限定する。

3.1.2 定数参照型モジュール

 いろいろなサブルーチンで使用する定数を、定数参照型モジュールにまとめる。include と異なり、use prm, only : imax などと使用したいパラメータだけ use できる。また、この場合、prm にimax の宣言がなければコンパイル時にエラーが発生してくれて、親切である。

定数参照型モジュールの例1 (prm_resol.F90)

module prm_resol
!
! 配列の大きさ(解像度)等を表す変数を設定
!
  implicit none
  integer,parameter :: imax = 128
  integer,parameter :: jmax = 64
   ( 中略 )
end module prm_resol

定数参照型モジュールの例2 (prm_phconst.F90)

module prm_phconst
!
! 物理定数を表す変数を設定する
!
  implicit none
  real(8),parameter :: cp   = 1004.6D0   ! 比熱
  real(8),parameter :: grav = 9.80665D0  ! 重力定数
  real(8),parameter :: gasr = 287.04D0   ! 気体定数
   ( 中略 )
end module prm_phconst

上記定数参照型モジュールを参照等をするメインプログラムの例 (main.F90)

program main
!
!  温度・高度データを標準入力して、エネルギーを標準出力する
!
  use prm_resol  , only : imax           ! 使うものだけをあげよう
  use prm_phconst, only : cp , grav
  implicit none
!
  real(8) :: energy     (imax)               
  real(8) :: height     (imax)               
  real(8) :: tmperature (imax)
  integer :: i
!
  read (5,*) tmperature
  read (5,*) height
  do i=1,imax
    energy(i) = cp * tmperature(i) + grav * height(i)
  enddo
  write(6,*) energy
end program main

 定数参照型モジュール内の定数の値は、コンパイル時に読み込まれるので、コンパイラが最適化を行いやすくなる。実行時に値を変更することは、もちろんできない。

3.1.3 変数参照型モジュール

 いろいろなサブルーチンで使用する変数を、変数参照型モジュールにまとめることができる。

 変数参照型モジュール内の共有変数の値の設定・変更は、同じモジュール内のサブルーチンでしか行ってはいけない。外部からは値を参照するのみにする。

変数参照型モジュールの例 (com_tetens.F90)

module com_tetens
  implicit none
  real(8), save :: table(25000)          ! 共有変数
!
contains
!
subroutine com_tetens__ini               ! 初期化サブルーチン
        : (table(25000)の値の設定を行う)
end subroutine com_tetens__ini
!
end module com_tetens

上記変数参照型モジュールを参照等をするメインプログラムの例 (main.F90)

program main
  use com_tetens,only: &
   & com_tetens__ini,  &                 ! サブルーチンcom_tetens__iniを使用。
   & table                               ! 変数tableを使用。
        :
  call com_tetens__ini                   ! tableの値の設定
        :   (以下、table(25000)の値を参照可能。変更はしない(ルール)。)
        :
end program main

 変数参照型モジュールの共有変数は、プログラム実行時に最初に一度だけ値を設定し、それ以後変更しないのが理想である。値の変更がある変数については、変数参照型モジュールではなく、引数でサブルーチンに渡す方がプログラムが分かりやすくなる場合が多いであろう。

3.1.4 パッケージ型モジュール

 パッケージ型モジュール内の共有変数や局所サブルーチンには private 属性をつけ、モジュール内でのみ使用し外部から直接使用しないようにする。外部とのやりとりは、初期化サブルーチンと実行サブルーチンだけを通じて行う。

 初期化サブルーチンで共有変数の初期値の設定を行う。

 実行サブルーチンはパッケージ型モジュール内に1個もしくは複数個あり、パッケージ型モジュールのメインの部分である。引数を通じて外部からデータを入力し、計算を行い、引数を通じて外部に必要なデータを出力する。

パッケージ型モジュールの例 (package1.F90)

module package1
  use prm_resol, only : imax,jmax
  implicit none
  private                                ! private属性をdefaultに
  public :: package1__ini, package1__run ! 外部から使用可
  real(8), save :: kyouyuu(imax,jmax)    ! 共有変数、外部から使用不可
!
contains
!
subroutine package1__ini(a)              ! 初期化サブルーチン
  real(8), intent(in) :: a(imax,jmax)
        :  (kyouyuu(imax,jmax)に初期値を与える)
        :  (データの入力は、例えば、引数から・NAMELISTから・ファイルから)
        :
end subroutine package1__ini
!
subroutine package1__run(b,c)            ! 実行サブルーチン
  real(8), intent(in)  :: b(imax,jmax)
  real(8), intent(out) :: c(imax,jmax)
        :
  call sub1
        :  (kyouyuu,bの値から、cの値を計算する。)
        :  (kyouyuuの値の変更も可。)
end subroutine package1__run
!
subroutine sub1                          ! 局所サブルーチン
        :  (モジュール内部でのみ使用)
end subroutine sub1
!
end module package1

 パッケージ型モジュール内でのみ使用する予報変数をモジュール内の共有変数にし、外部から隠蔽する。パッケージ型モジュール内でのみ使用するサブルーチンを局所サブルーチンにし、これも外部から隠蔽する。初期化サブルーチンと実行サブルーチンのインターフェースのみを外部に公開する。

 このようにして個々のモジュールの独立性を高めることにより、プログラム全体の構造が分かりやすくなり、多人数で大規模なプログラムの共同開発を行うことが容易になる。

3.1.5 モジュールの階層構造

 上の階層のモジュールが下の階層のモジュールをuseし使用する形になる。コンパイル時には、下の階層のモジュールから順にコンパイルしなければいけない。
 サブルーチンはモジュールに属するようにする。サブルーチンの属するモジュールを use してからでないとそのサブルーチンを使用できなくなるが、コンパイラがコンパイル時に引数の型が一致しているかどうかチェックを行ってくれるというメリットがある。これによりデバッグが容易になる。

3.2 動的割り付け

 サブルーチン内のワーク的変数を動的にメモリに割り付けることにより、プログラム作成者はワーク的変数の管理から開放され、メモリを有効利用することができる。また実行時に配列の大きさを変更できるので、解像度に依存しないプログラムが作成できる。

動的割り付けサブルーチンの例 (sub.F90)

subroutine sub( imax, jmax, a )
  implicit none
  integer, intent(in)    :: imax
  integer, intent(in)    :: jmax
  real(8), intent(inout) :: a(imax,jmax)
!
  real(8) :: work1(imax,jmax)            ! 自動配列
  real(8), allocatable :: work2(:,:)     ! allocate可能な配列
!
  allocate(work2(imax,jmax))             ! メモリに割り付ける。
        :  (aの値を計算する。)
        :
  deallocate(work2)                      ! メモリを解放する。
end subroutine sub

 上の例で、自動配列は自動的にサブルーチンの初めにメモリに割り付けられ、サブルーチンの終わりにメモリを解放する。allocatable 配列では、allocate 文、deallocate 文で明示的に行う。

 自動配列はメモリのスタック領域を使用する場合が多く、ヒープ領域を使用する場合が多いallocatable 配列より自動配列の方が割付を高速に行えることが多い。しかし、使用可能なスタックのサイズに制限がある場合があり、自動配列で使用できるメモリが制限される場合がある。(OS・コンパイラによる。)

4.禁止事項

4.1 記憶列結合

4.2 新機能のうち冗長なもの

4.3 冗長な旧機能

4.4 廃止予定事項

多重の do ループを同じ文番号で終えることはできなくなる予定。また、do ループを end do 文でも continue 文でもない単純実行文で終えることはできなくなる予定。代わりに end do を用いること。

4.5 その他

5.現段階では規定していないが重要なもの

書式は機種依存であるが、機能的にはほぼ同等のものが各処理系に存在する。#include を使って切り替える、などというルールが必要か。

付録 気象予報モデル・データ同化プログラムのためのコメント

 ここでは、一般的に禁止あるいは非推奨事項とはしないが、気象予報モデル・データ同化プログラムのために特記すべき事項を記述する。「5.現段階では規定しない」事項にも言及している。


参考文献

参考URL


変更履歴(誤字脱字の修正等は含まれません)


<本コーディングルール作成に携わった人々>

 室井ちあし   気象研究所予報研究部(←気象庁予報部数値予報課)
 豊田英司    気象庁予報部数値予報課
 吉村裕正    気象研究所気候研究部
 保坂征宏    気象研究所気候研究部
 杉正人     気象研究所気候研究部

 本ルールについて、気象庁内外の多くの方からコメントをいただいています。名前はここには記しませんが、関心をもっていただいている皆さんに感謝しています。