すべての関数とサブルーチンの中にimplicit none
を入れる必要がありますか?
それとも、これらの関数とサブルーチンを含むモジュールの先頭に置くだけで十分ですか?
それとも、これらのモジュールを使用しているプログラムの先頭に置くだけで十分ですか?
他人の作業コードを観察すると、implicit none
はこれらすべての場所に含まれています。サブルーチンからimplicit none
を削除しても、コンパイルされて同じ出力が生成されるため、これが冗長に行われているかどうかはわかりません。
ちなみに、私はgfortran fortran 90
を使用しています。
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
で有効な場合、そのステートメントがなくても有効かつ同一でなければなりません。前者の場合、すべてのエンティティを明示的に宣言する必要があるため、後者には暗黙のルールは適用されません。
いいえ、はい(種類)およびいいえ.
プログラム単位ごとに1回(プログラムごとに1回と同じではありません)、各インターフェース本体で十分です。
プログラム単位は、メインプログラム、モジュール、外部サブプログラム(別のタイプのプログラム単位のCONTAINSステートメントの後に現れない関数またはサブルーチンサブプログラム)、ブロックデータプログラム単位、またはサブモジュールのいずれかです。 IMPLICITステートメントで特に指定されていない限り、各プログラムユニットのデフォルトは、デフォルトの整数としてI-Nで始まるもののデフォルトマッピングであり、それ以外はすべてデフォルトの実数です。
同じ原則がインターフェース本体にも適用されます。インターフェース本体は、別のプログラム単位で定義されたプロシージャーの指定部分のスナップショットであると想定されているためです。特に指定しない限り、他のプログラム単位にはデフォルトのマッピングがあるため、特に指定しない限り、インターフェース本体にはデフォルトのマッピングがあります。
プログラムユニット内では、内部サブプログラムまたはモジュールサブプログラムは、適切なサブプログラム内に「ローカル」IMPLICITステートメントがない場合、ホストで指定された暗黙の型指定を継承します。
IMPLICIT NONEの冗長指定は無害です。以前は外部サブプログラムであったサブプログラムがモジュールに配置されている場所をよく目にします。
これは私にとって何がうまくいくかに基づいた非公式の回答です。
私のFortranコードは、メインプログラムを含むファイルと単一のモジュールを含むファイルの2種類のファイルにあります。各種類のファイルで、IMPLICIT NONEは、「program foo」または「module foo」ステートメントの直後、および先頭のUSEステートメントの直後に表示されます。冗長であるため、サブルーチンまたは関数内には表示されません。
gfortran
を使用している場合は、単純に -fimplicit-none
パラメータ。
これはコンパイラ固有のソリューションであることに注意してください。他の広範なコンパイラはこのパラメータをサポートしない場合があります。たとえば、Intelのifort
はこれを不明なオプションとして無視します。