エラー処理サブルーチンでのループの防止
前の例では、*PSSR でエラーが起こるため、ループの起こる可能性は少なくなっています。 しかし、*PSSR がどのように書かれるかによって、*PSSR の処理中に例外が起こるとループが起こる可能性があります。
このようなループを避ける 1 つの方法として、 サブルーチンに初回の実行を示すスイッチを設定することができます。 サブルーチンの初回の実行でない場合には、ENDSR 命令の演算項目 2 に *CANCL などの 適切な戻り点を指定することができます。
図 1 には、*PSSR サブルーチン内でのループを避ける方法を
示すために例外を生成するように設計されたプログラム NOLOOP を示してあります。
このプログラムは例外を次の 2 回生成します。
- コードの本体で *PSSR に制御権を渡すため
- *PSSR 内部で潜在的にループを起こすため
図 1. エラー処理サブルーチンでのループの防止
*=================================================================*
* NOLOOP: *PSSR サブルーチンの反復を回避する方法を示します。 *
*=================================================================*
*-----------------------------------------------------------------*
* エラーを起こすために使用する配列 *
*-----------------------------------------------------------------*
D Arr1 S 10A DIM(5)
*-----------------------------------------------------------------*
* 配列の範囲外エラーを生成し、制御を *PSSR に渡します。 *
*-----------------------------------------------------------------*
C Z-ADD -1 Neg1 5 0
C MOVE Arr1(Neg1) Arr1(Neg1)
C MOVE *ON *INLR
*=================================================================*
* *PSSR: プロシージャーのエラー処理サブルーチン。PSSR の反復を検出*
* するために変数 InPssr を使用します。 *
* 反復を検出した場合には、プロシージャーを *CANCL します。 *
*=================================================================*
C *PSSR BEGSR
C IF InPssr = 1
C MOVE '*CANCL' ReturnPt 6
C Z-ADD 0 InPssr 1 0
C ELSE
C Z-ADD 1 InPssr
* *
* サブルーチンがプロシージャーを取り消す方法を見るために *
* ここで PSSR に別のエラーを生成します。 *
* *
C MOVE Arr1(Neg1) Arr1(Neg1)
* *
* Neg1 がまだ負の場合には、次の 2 つの命令は処理されない *
* ことに注意してください。 *
* *
C MOVE '*GETIN' ReturnPt
C Z-ADD 0 InPssr
C ENDIF
C ENDSR ReturnPt
図 1 のソースを使ってプログラムを作成し、そのデバッグを
始めるには、次の入力をします。
CRTBNDRPG PGM(MYLIB/NOLOOP) DBGVIEW(*SOURCE)
STRDBG PGM(MYLIB/NOLOOP)
*PSSR サブルーチンの BEGSR 行に中断点を設定することにより、*PSSR サブルーチンを ステップスルーすることができます。
プログラムを呼び出すと、次のことが起こります。
- プログラムが負の指標を使用して配列に MOVE 命令を実行しようとすると、 例外が起こります。制御が *PSSR に渡されます。
- これが *PSSR の最初の実行であるので、変数 In_Pssr はまだオンに設定されていません。 将来のループを防止するために変数 In_Pssr がオンに設定されます。
- 処理は、*PSSR 内の ELSE の後の MOVE で続行されます。 再び例外が起こり、*PSSR の処理が新たに始まります。
- 今回の実行では変数 In_Pssr が既に 1 に設定されています。 これはサブルーチンがループ状態にあることを示しているので、ReturnPt フィールドを *CANCL に 設定することによってプロシージャーが取り消されます。
- ENDSR 命令が制御を受け取り、プロシージャーが取り消されます。
ループを避けるためにここで用いた方法は、INFSR エラー処理サブルーチン内でも使用することができます。