11.7 プログラム単位と手続き
-
[7.0]
OPERATOR総称の一部である関数の仮引数にVALUE属性がある場合、INTENT(IN)属性を持つ必要がなくなりました。例)
INTERFACE OPERATOR(+) MODULE PROCEDURE logplus END INTERFACE ... PURE LOGICAL FUNCTION logplus(a,b) LOGICAL,VALUE :: a,b logplus = a.OR.b END FUNCTION -
[7.0]
ASSIGNMENT総称の一部であるサブルーチンの2番目の引数にVALUE属性がある場合、INTENT(IN)属性を持つ必要がなくなりました。例)
INTERFACE ASSIGNMENT(=) MODULE PROCEDURE asgnli END INTERFACE ... PURE SUBROUTINE asgnli(a,b) LOGICAL,INTENT(OUT) :: a INTEGER,VALUE :: b DO WHILE (IAND(b,NOT(1))/=0) b = IEOR(IAND(b,1),SHIFTR(b,1)) END DO a = b/=0 ! Odd number of "1" bits. END SUBROUTINE -
[7.0]
-recursiveまたは-f2018オプションを使用すると、手続きはデフォルトで再帰的になります。
例)INTEGER FUNCTION factorial(n) RESULT(r) IF (n>1) THEN r = n*factorial(n-1) ELSE r = 1 END IF END FUNCTION上記サブプログラムはRECURSIVEキーワードで明示的に宣言されているかのように有効です。これは、サイズ引継ぎ文字関数には適用されません(結果が
CHARACTER(LEN=*)で宣言されている場合、これらはRECURSIVEで宣言されないままです。)デフォルトで
RECURSIVEの手続きは、RECURSIVEとして明示的に宣言されている場合とまったく同じように、-save省略可能な効果から除外されることに注意してください。 -
[7.0]
RECURSIVEが明示的に宣言されているか、デフォルトで(-f2018または-recursiveオプションが指定されている場合)、要素別処理手続きが再帰的になる可能性があります。
例)ELEMENTAL RECURSIVE INTEGER FUNCTION factorial(n) RESULT(r) INTEGER,INTENT(IN) :: n IF (n>1) THEN r = n*factorial(n-1) ELSE r = 1 END IF END FUNCTION上記は以下のように呼び出すことが可能です。PRINT *,factorial( [ 1,2,3,4,5 ] )これにより最初の5つの階乗を出力されます。 -
NON_RECURSIVEキーワードは、手続きが再帰的に呼び出されないことを明示的に宣言します。
例)NON_RECURSIVE INTEGER FUNCTION factorial(n) RESULT(r) r = 1 DO i=2,n r = r*i END DO END FUNCTIONFortran 2008以前の標準では、手続きがデフォルトで非再帰的であるため、 -recursiveまたは-f2018が使用されていない限り、このキーワードは効果がありません。
-
総称解決は手続き引数の数を使用することができます。つまり、ある手続きが他の手続きよりも多くの非オプションの
手続き引数を持つ場合、その手続きはオプションの手続き引数と非オプションの手続き引数を合わせたものよりも多いと、手続きは
明確とみなされます。
例えば、
MODULE npa_example INTERFACE g MODULE PROCEDURE s1,s2 END INTERFACE CONTAINS SUBROUTINE s1(a) EXTERNAL a CALL a END SUBROUTINE SUBROUTINE s2(b,a) EXTERNAL b,a CALL b CALL a END SUBROUTINE END MODULEこの例は、引数Aが位置によっては区別されるがキーワードによっては区別されない、 引数Bはキーワードによっては区別されるが位置によっては区別されない、 そして位置による区別者(A)がリストの中でキーワードによる区別者(B)よりも前に現れないため、 Fortran 2008の明確な総称手続きのルールに従っていません。 -
[7.2]
GENERIC文は、総称インターフェースを宣言する簡潔な方法を提供します。 その構文は以下の通りです:
ここで、任意の アクセス指定 はGENERIC[ , アクセス指定 ]::総称指定=>手続き名リストPUBLICまたはPRIVATE、 総称指定 は総称識別子(名前、ASSIGNMENT(=)、OPERATOR(op)、または {READ|WRITE}({FORMATTED|UNFORMATTED}))であり、 そして 手続き名リスト は、名前付き手続きのカンマ区切りリストです。アクセス指定 は、
GENERIC文がモジュールの仕様部分にある場合のみ許可されます。 リスト内の各名前付き手続きは、明示的な引用仕様を持たなければなりません。つまり、内部 手続き、モジュール手続きであるか、または引用仕様宣言もしくは手続き宣言文で明示的な引用仕様を指定して宣言されていなければなりません。 総体的に、手続きはすべて関数であるかすべてサブルーチンであり、明確であるという通常の総称ルールを満たさなければなりません。アクセス指定 を除き、
GENERIC文はINTERFACE 総称指定 PROCEDURE 手続き名リスト END INTERFACEと同じ効果を持ちます。 唯一の利点は、それが数行短く、同じ行でアクセス可能性を宣言できることです。 この構文は派生型定義の 総称束縛 と同じですが、 名前のリストは型に束縛された手続きではなく通常の名前付き手続きのものです。例えば、プログラム
Module print_sqrt Private Generic,Public :: g => s1, s2 Contains Subroutine s1(x) Print '(F10.6)',Sqrt(x) End Subroutine Subroutine s2(n) Print '(I10)',Nint(Sqrt(Real(n))) End Subroutine End Module Program test Use print_sqrt Call g(2.0) Call g(127) End Programは1.414214 11を出力します。 -
[7.2]
他のモジュール(
USE文を介して)からアクセスされるモジュール内の要素のデフォルトのアクセシビリティは、 そのモジュール名をPUBLICまたはPRIVATE文で指定することによって制御でき、 インポートするモジュールの他の要素のデフォルトのアクセシビリティを上書きできます。 例えば、Module mymod Use Iso_Fortran_Env Real(real32) x Integer(int64) y Private Iso_Fortran_Env End Moduleでは、ISO_FORTRAN_ENVのすべての要素はデフォルトでモジュールmymodでPRIVATEです、 個別にリストする必要はありません。この新しいデフォルトのアクセシビリティは、明示的な
PUBLICまたはPRIVATE宣言によって上書きできます。 また、リモートモジュール(2つ以上のUSE文がある)の要素がより多くの 介在するモジュールによってアクセスされる場合、その要素へのすべての経路がデフォルトでPRIVATEの場合にのみデフォルトでPRIVATEになり、 任意の経路がデフォルトでPUBLICの場合はデフォルトでPUBLICになります。 例えば、Module remote Real a,b End Module Module route_one Use remote Private remote End Module Module route_two Use remote End Module Module my_module Use route_one Use route_two Private route_one End Moduleでは、モジュールREMOTEの変数AとBはモジュールMY_MODULEでPUBLICです、 それらはデフォルトでPUBLICであるモジュールROUTE_TWOを介してアクセス可能です。
