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 FUNCTION
Fortran 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
を介してアクセス可能です。