web-dev-qa-db-ja.com

Fortranで「暗黙のなし」をどこに置くか

すべての関数とサブルーチンの中にimplicit noneを入れる必要がありますか?

それとも、これらの関数とサブルーチンを含むモジュールの先頭に置くだけで十分ですか?

それとも、これらのモジュールを使用しているプログラムの先頭に置くだけで十分ですか?

他人の作業コードを観察すると、implicit noneはこれらすべての場所に含まれています。サブルーチンからimplicit noneを削除しても、コンパイルされて同じ出力が生成されるため、これが冗長に行われているかどうかはわかりません。

ちなみに、私はgfortran fortran 90を使用しています。

28
Fabricator

implicitステートメント(implicit noneを含む)は、スコープ単位に適用されます。そのようなことは

BLOCK構文、派生型定義、インターフェース本体、プログラム単位、またはサブプログラム(ネストされたスコープ単位をすべて除外)

この「ネストされたスコープユニットをすべて除外する」ということは、モジュールで定義されている各関数とサブルーチン(まとめてプロシージャ)にimplicit noneを含めることが必要/望ましい場合があることを示唆しています。ただし、モジュール内に含まれるプロシージャ内には、Host有効範囲単位に基づくデフォルトのマッピングがあります。したがって、モジュールにimplicit noneを使用すると、含まれているプロシージャにそれを含める必要はありません。

このホストスコープユニットルールは、内部プログラムにも同様に適用されます。つまり、メインプログラムのimplicit noneは、メインプログラムに含まれるすべてのプロシージャをカバーします。モジュールプロシージャの内部プログラムについても同様です。ブロック構造もこれを参照し、implicitステートメントはこれらのいずれか内では許可されていません。

ただし、外部関数/サブルーチンはプログラムまたはモジュールから暗黙の動作を継承せず、モジュールはそれらをuseするプログラム/他のモジュールからそれを継承しません。暗黙の型指定はコンパイル時に認識され、最終的な使用に関係なく明確に定義される必要があるため、これは明らかに意味があります。

さらに、

implicit none
use somemodule

end program

implicitステートメントは、すべてのuseステートメントの後に続く必要があります。

このホストスコーピングユニットルールは、特にインターフェース本体には適用されません。 IanHの答え はその例外を動機付けますが、ストレスを解消するには十分重要です。多くの混乱を引き起こしています。

module mod
 implicit none

  interface
    subroutine external_sub()
      ! The default implicit typing rules apply here unless there is an implicit
      ! statement, such as implicit none.  Those from the module aren't in force here.
    end subroutine
  end interface

end module

サブルーチンからimplicit noneを削除するテストについて:コードがimplicit noneで有効な場合、そのステートメントがなくても有効かつ同一でなければなりません。前者の場合、すべてのエンティティを明示的に宣言する必要があるため、後者には暗黙のルールは適用されません。

23
francescalus

いいえ、はい(種類)およびいいえ.

プログラム単位ごとに1回(プログラムごとに1回と同じではありません)、各インターフェース本体で十分です。

プログラム単位は、メインプログラム、モジュール、外部サブプログラム(別のタイプのプログラム単位のCONTAINSステートメントの後に現れない関数またはサブルーチンサブプログラム)、ブロックデータプログラム単位、またはサブモジュールのいずれかです。 IMPLICITステートメントで特に指定されていない限り、各プログラムユニットのデフォルトは、デフォルトの整数としてI-Nで始まるもののデフォルトマッピングであり、それ以外はすべてデフォルトの実数です。

同じ原則がインターフェース本体にも適用されます。インターフェース本体は、別のプログラム単位で定義されたプロシージャーの指定部分のスナップショットであると想定されているためです。特に指定しない限り、他のプログラム単位にはデフォルトのマッピングがあるため、特に指定しない限り、インターフェース本体にはデフォルトのマッピングがあります。

プログラムユニット内では、内部サブプログラムまたはモジュールサブプログラムは、適切なサブプログラム内に「ローカル」IMPLICITステートメントがない場合、ホストで指定された暗黙の型指定を継承します。

IMPLICIT NONEの冗長指定は無害です。以前は外部サブプログラムであったサブプログラムがモジュールに配置されている場所をよく目にします。

6
IanH

これは私にとって何がうまくいくかに基づいた非公式の回答です。

私のFortranコードは、メインプログラムを含むファイルと単一のモジュールを含むファイルの2種類のファイルにあります。各種類のファイルで、IMPLICIT NONEは、「program foo」または「module foo」ステートメントの直後、および先頭のUSEステートメントの直後に表示されます。冗長であるため、サブルーチンまたは関数内には表示されません。

5
Fortranner

gfortranを使用している場合は、単純に -fimplicit-none パラメータ。

これはコンパイラ固有のソリューションであることに注意してください。他の広範なコンパイラはこのパラメータをサポートしない場合があります。たとえば、Intelのifortはこれを不明なオプションとして無視します。

1
marmistrz