この規格ページの目次
412
附属書 C
X 3001-1 : 2009 (ISO/IEC 1539-1 : 2004)
Fortran プログラマが,これらの実数の配列に対するメッセージ渡しライブラリから言語 C の手続を使うとする。
この手続の言語 C 関数原型は
void ProcessBuffer(void *buffer, int n_bytes);
であり,対応する Fortran 引用仕様は,次のとおりである。
USE, INTRINSIC :: ISO_C_BINDING
INTERFACE
SUBROUTINE PROCESS_BUFFER(BUFFER,N_BYTES) BIND(C,NAME="ProcessBuffer")
IMPORT :: C_PTR, C_INT
TYPE(C_PTR), VALUE :: BUFFER ! 配列 buffer の C アドレス
INTEGER(C_INT), VALUE :: N_BYTES ! buffer 内のバイト数
END SUBROUTINE PROCESS_BUFFER
END INTERFACE
もし Fortran 処理系の C LOC が適切なアドレスを返すならば,これは C LOC を用いて行える。
REAL(R_QUAD), DIMENSION(:), ALLOCATABLE, TARGET :: QUAD_ARRAY
...
CALL PROCESS_BUFFER(C_LOC(QUAD_ARRAY), INT(16*SIZE(QUAD_ARRAY),C_INT))
! この処理系では一つの quad 実数型は,16 バイトをとる
C.10.2.4 言語 C と Fortran との間の不透明な連絡の例
次の例は,C プログラムから利用できる現代的なオブジェクト指向乱数生成器の Fortran での作り方を示している。
USE, INTRINSIC :: ISO_C_BINDING
! このコードはモジュール内にあると仮定
TYPE RANDOM_STREAM
! 一様乱数生成器 (URNG-Uniform Random Number Generator)
CONTAINS
PROCEDURE(RANDOM_UNIFORM), DEFERRED, PASS(STREAM) :: NEXT
! ストリームから次の数を生成
END TYPE RANDOM_STREAM
ABSTRACT INTERFACE
! Fortran の URNG の抽象引用仕様
SUBROUTINE RANDOM_UNIFORM(STREAM, NUMBER)
IMPORT :: RANDOM_STREAM, C_DOUBLE
CLASS(RANDOM_STREAM), INTENT(INOUT) :: STREAM
REAL(C_DOUBLE), INTENT(OUT) :: NUMBER
END SUBROUTINE RANDOM_UNIFORM
END INTERFACE
基底型 RANDOM STREAM の多相的実体は,C と相互利用可能ではない。しかし,多相的でもなくパラメタ付けされて
もいない別の派生型の中にそれをパッケージ化することによって,言語 C で利用できるそのような乱数生成器を作る
ことができる。
TYPE :: URNG_STATE ! この型は相互利用可能ではないので BIND(C) は書かない
CLASS(RANDOM_STREAM), ALLOCATABLE :: STREAM
END TYPE URNG_STATE
次の二つの手続によって,言語 C のプログラムから Fortran 一様乱数生成器が利用できるようになる。
! 一様乱数生成器の初期化
SUBROUTINE INITIALIZE_URNG(STATE_HANDLE, METHOD) &
BIND(C, NAME="InitializeURNG")
TYPE(C_PTR), INTENT(OUT) :: STATE_HANDLE
! URNG に対する不透明なハンドル
――――― [JIS X 3001-1 pdf 426] ―――――
413
附属書 C
X 3001-1 : 2009 (ISO/IEC 1539-1 : 2004)
CHARACTER(C_CHAR), DIMENSION(*), INTENT(IN) :: METHOD
! 使用されるアルゴリズム
TYPE(URNG_STATE), POINTER :: STATE
! 実際の URNG 実体
ALLOCATE(STATE)
! この例では示さないが,メモリリークを避けるために対応する後始末が必要
! METHOD に依存する実行時の型で STATE%STREAM を割り付ける
...
STATE_HANDLE=C_LOC(STATE)
! 言語 C に戻るために不透明なハンドルを獲得
END SUBROUTINE INITIALIZE_URNG
! 乱数の生成
SUBROUTINE GENERATE_UNIFORM(STATE_HANDLE, NUMBER) &
BIND(C, NAME="GenerateUniform")
TYPE(C_PTR), INTENT(IN), VALUE :: STATE_HANDLE
! INITIALIZE_URNG の呼出しによって得られた不透明なハンドル
REAL(C_DOUBLE), INTENT(OUT) :: NUMBER
TYPE(URNG_STATE), POINTER :: STATE
! 実際の URNG へのポインタ
CALL C_F_POINTER(CPTR=STATE_HANDLE, FPTR=STATE)
! 不透明なハンドルを使用可能なポインタに変換
CALL STATE%STREAM%NEXT(NUMBER)
! NUMBER を生成するために型束縛手続 NEXT を使用
END SUBROUTINE GENERATE_UNIFORM
C.11 箇条 16 の注記
C.11.1 親子結合の例(16.4.1.3 参照)
親子結合の正しい例を例 1. 及び 例 2. に,誤った例を例 3. に示す。
例 1. 正しい親子結合
PROGRAM A
INTEGER I, J
...
CONTAINS
SUBROUTINE B
INTEGER I ! I を宣言したことによって,プログラム A での I の宣言が隠れる。
...
I = J ! 親子結合によって,プログラム A の変数 J を使用する。
END SUBROUTINE B
END PROGRAM A
例 2. 正しい親子結合
PROGRAM A
TYPE T
...
END TYPE T
...
CONTAINS
SUBROUTINE B
IMPLICIT TYPE (T) (C) ! 上のプログラム A 内で宣言した型 T ではなく,
――――― [JIS X 3001-1 pdf 427] ―――――
414
附属書 C
X 3001-1 : 2009 (ISO/IEC 1539-1 : 2004)
! 下のサブルーチン B 内で宣言する型 T を参照する。
...
TYPE T
...
END TYPE T
...
END SUBROUTINE B
END PROGRAM A
例 3. 誤った親子結合
PROGRAM Q
REAL (KIND = 1) :: C
...
CONTAINS
SUBROUTINE R
REAL (KIND = KIND (C)) :: D ! この宣言は誤り。下の本文参照。
REAL (KIND = 2) :: C
...
END SUBROUTINE R
END PROGRAM Q
サブルーチン R で D の宣言に使用している C は,プログラム Q で宣言された C ではなくサブルーチン
R 内で宣言された C を参照していることになる。しかし,C は D の宣言で使用するよりも前に宣言してお
かなければならない(7.1.7 参照)ので,これは誤りである。
C.11.2 明白な総称を保証する規則(16.2.3 参照)
16.2.3 の規則は,次のことを保証する。
総称の集合中で,個別手続それぞれの引用を可能にすること。
総称手続を正しく引用するために,引用される個別手続が明白に決定されること。
引用される個別手続が,プログラムの実行開始前(翻訳中)に決定されること。
個別手続は,特定の型,種別型パラメタ 及び 次元数の引数に固定した性質によって区別される。総称集合中のあ
る手続の正しい引用は,他の手続が受け入れられない引数をもっていること,他の手続が必要とする引数をもってい
ないこと 又は 固定した性質の一つが異なっていることによって,他の手続の引用とは区別される。
データ要素の宣言時の型は固定した性質をもつが,多相的な変数は,ある制約下で仮引数と実引数との型の不一致
が許されている。二つの仮引数を区別する条件は,型が適合していないことであり,単に型が異なるだけではない。
(これは,後にこの細分箇条に出てくる例 BAD6 で示されている。)
同じ制約下での型の不一致は,型が適合している二つの仮引数が共通にもっている種別型パラメタの値に基づいて
区別されることを意味する。もしそれらの一つが,他方がもっていない種別型パラメタをもっていても,それらを区
別するのには関係がない。
次元数は固定した性質であるが,手続が個別名で引用されるとき,配列の仮引数の幾つかの形式では,次元数が一
致していなくてもよい。次元数が常に総称を区別するのに使えるようにするため,手続が総称として引用されるとき
は,それらの引数について次元数の不一致は許されない。更に,要素別処理手続が配列引数を受け入れられるという
事実は,これらの規則を適用するときに考慮されない。要素別処理手続とそうでない手続との間には,明らかなあい
まいさがある。その場合,その引用は,要素別処理でない手続への引用と解釈される。
演算子 又は 利用者定義代入として引用された手続では,構文的に区別された引数は,引数リストの中の個別の位
置に配置される。それらの手続を区別する規則は,引数の位置の一つによって引数を区別することが可能であるとい
うことである。
――――― [JIS X 3001-1 pdf 428] ―――――
415
附属書 C
X 3001-1 : 2009 (ISO/IEC 1539-1 : 2004)
利用者定義の派生型入出力手続では,引数 dtv だけがそのプログラム内で明示的に書くものであり,区別する必要
がある。引数 dtv はスカラである必要があるので,それらは次元数では区別できない。したがって,この規則は,実
際には型 及び 種別型パラメタだけに影響する。
名前で識別される総称手続では,規則は更に複雑となる。それは,省略可能な引数が省略されたり,引数が位置 又
は 名前のいずれかによって指定されるからである。
当該実体仮引数をもつ型束縛手続という特別な場合,当該実体仮引数は,構文で区別して参照される。そのとき,
規則 (2) が適用される。当該実体仮引数の型は,同じ有効域内の当該実体仮引数が型不適合とならない手段を強いる。
したがって,この規則は,実際には種別型パラメタ 及び 次元数だけに影響する。
名前付けられた総称を区別する主な手段は,規則 (3) である。その規則の最もよくある応用は,単一の引数が (3a)
及び (3b) の両方を満足することである。
INTERFACE GOOD1
FUNCTION F1A(X)
REAL :: F1A,X
END FUNCTION F1A
FUNCTION F1B(X)
INTEGER :: F1B,X
END FUNCTION F1B
END INTERFACE GOOD1
GOOD1(1.0) 又は GOOD1(X=1.0) と書くと,F1A の引用になる。これらの引用が実数の定数値 1.0 を与えているの
に対して,F1B が整数の引数を必要としているからである。
この例 及び 以降の例は,区別する性質としての型をもつ引用仕様本体を示している。これは,それらの例を書い
たり示したりすることをより容易にしている。ここで示されている原則は,それらの手続が他のある手段で明示的引
用仕様をもつとき 又は 種別型パラメタ 若しくは 次元数が区別する性質であるとき,等しく適用できる。
一つのよくある形は,引数が一方の個別手続には必要とされ,他方には全く存在しないことによって,(3a) 及び
(3b) を満足するものである。
INTERFACE GOOD2
FUNCTION F2A(X)
REAL :: F2A,X
END FUNCTION F2A
FUNCTION F2B(X,Y)
COMPLEX :: F2B
REAL :: X,Y
END FUNCTION F2B
END INTERFACE GOOD2
GOOD2(0.0,1.0),GOOD2(0.0,Y=1.0) 又は GOOD2(Y=1.0,X=0.0) と書くと,F2B の引用になる。F2A は,2 番目
の位置に引数をもたないし,名前 Y である引数ももたないからである。この方法は,引数が存在するかどうかによっ
て,関数に異なる結果の型,異なる種別型パラメタ 又は 異なる次元数をもたせたいとき,省略可能な引数に対する
一つの代替手段として使われる。組込み関数の多くで,引数 DIM はこのように働く。
引数を異なる位置 及び 名前によって区別することも可能である。
INTERFACE GOOD3
SUBROUTINE S3A(W,X,Y,Z)
REAL :: W,Y
INTEGER :: X,Z
END SUBROUTINE S3A
SUBROUTINE S3B(X,W,Z,Y)
REAL :: W,Z
――――― [JIS X 3001-1 pdf 429] ―――――
416
附属書 C
X 3001-1 : 2009 (ISO/IEC 1539-1 : 2004)
INTEGER :: X,Y
END SUBROUTINE S3B
END INTERFACE GOOD3
S3A を引用するために GOOD3(1.0,2,3.0,4) と書くと,3 番目 及び 4 番目の引数が S3B の引用に一致するが,1 番
目 及び 2 番目の引数は S3B の引用に一致しない。S3B への引用と一致させるために,最初の二つの引数を引数キーワー
ドを使って入れ換えて書いた場合,最後の二つの引数は,引数キーワードを使って GOOD3(X=2,W=1.0,Z=4,Y=3.0)
と書かなければならない。このとき,名前付けされた引数 Y 及び 引数 Z は区別される。
規則 (3) の順序の条件は,重要である。
INTERFACE BAD4 ! この引用仕様は正しくない。
SUBROUTINE S4A(W,X,Y,Z)
REAL :: W,Y
INTEGER :: X,Z
END SUBROUTINE S4A
SUBROUTINE S4B(X,W,Z,Y)
REAL :: X,Y
INTEGER :: W,Z
END SUBROUTINE S4B
END INTERFACE BAD4
この例では,引数 Y 及び 引数 Z は位置によって区別され,引数 W 及び 引数 X は名前によって区別される。この順
番で,BAD4(1.0,2,Y=3.0,Z=4) と書くことは可能であるが,S4A 及び S4B の両方を正しく引用することになる。
規則 (1) では,規則 (3) で対応できない幾つかの場合を区別することができる。
INTERFACE GOOD5
SUBROUTINE S5A(X)
REAL :: X
END SUBROUTINE S5A
SUBROUTINE S5B(Y,X)
REAL :: Y,X
END SUBROUTINE S5B
END INTERFACE GOOD5
規則 (3) を適用しようとすると,正しくない順番ではあるが,位置 2 及び 名前 Y は BAD4 の例のように区別でき
る。しかし,同じようなあいまいな引用を構成しようとしても,GOOD5(1.0,X=2.0) は,二つの異なる実引数を仮引
数 X と結合することになってしまうので,S5A の引用となることはない。S5B が二つの実引数を必要とすることを認
識すると,規則 (3) はこの場合に該当する。S5A は二つ以上の引数を受け入れることはできない。
規則 (1) の適用は,拡張可能型が現れるとき,更に複雑となる。FRUIT が拡張可能型であって,PEAR 及び APPLE
が FRUIT の拡張であり,BOSC が PEAR の拡張であるとき,一見すると,次の方法で区別可能に見えるが,制約され
た型の不一致が許されるので,BAD6(A PEAR,A BOSC) は S6A 及び S6B の両方への正しい引用となる。
INTERFACE BAD6 ! この引用仕様は正しくない。
SUBROUTINE S6A(X,Y)
CLASS(PEAR) :: X,Y
END SUBROUTINE S6A
SUBROUTINE S6B(X,Y)
CLASS(FRUIT) :: X
CLASS(BOSC) :: Y
END SUBROUTINE S6B
END INTERFACE BAD6
存在するそれぞれの型に対して規則 (1) を試みることは,重要である。
――――― [JIS X 3001-1 pdf 430] ―――――
次のページ PDF 431
JIS X 3001-1:2009の引用国際規格 ISO 一覧
- ISO/IEC 1539-1:2004(IDT)
JIS X 3001-1:2009の国際規格 ICS 分類一覧
- 35 : 情報技術.事務機械 > 35.060 : 情報技術に使用される言語
JIS X 3001-1:2009の関連規格と引用規格一覧
- 規格番号
- 規格名称