導入:なぜPERFORMの再入は禁じられるのか
COBOLの現場で長年保守を行っていると、時折「プログラムが突然暴走する」「意図しない場所へ制御が飛ぶ」という不可解な障害に遭遇することがあります。その原因の多くが、構造化プログラミングにおける基本中の基本である「PERFORM文の再入」を犯していることにあります。なぜこれが厳禁なのか、そしてどう回避すべきか、ベテランの視点から解説します。
基礎知識:PERFORMの仕組みとスタック破壊
COBOLの標準的な手続き(PROCEDURE DIVISION)は、再帰呼び出しを想定して設計されていません。PERFORM文が実行される際、COBOLの実行基盤は「次にどこへ戻るべきか」を示す「戻りアドレス」を内部スタックに保存します。
もし、ある段落の中で自分自身をPERFORMすると、このスタック情報が上書きされてしまいます。結果として、プログラムは正しい帰還先を見失い、無限ループに陥るか、最悪の場合はメモリ破壊を引き起こして異常終了(ABEND)に至ります。
実装と解決策:フラグ制御による構造化
再帰的な処理を行いたい場合、PERFORMを入れ子にするのではなく、「フラグによる制御」または「PERFORM THROUGHによる範囲指定」を用いるのが定石です。特に、ループ処理が必要な場合は、PERFORM文の中にIF文を組み込み、状態遷移を管理する設計に切り替えましょう。
サンプルプログラム:安全なループ処理の実装例
以下に、再入を避けつつ、再帰的なロジックを安全に実現するパターンを示します。
IDENTIFICATION DIVISION.
PROGRAM-ID. RECURSIVE-TEST.
WORKING-STORAGE SECTION.
01 WS-COUNTER PIC 9(02) VALUE 0.
01 WS-LOOP-FLG PIC X VALUE ‘Y’.
PROCEDURE DIVISION.
MAIN-LOGIC.
- 再入を避け、フラグ制御でループを構築する
PERFORM UNTIL WS-LOOP-FLG = ‘N’
PERFORM SUB-PROCESS
END-PERFORM.
STOP RUN.
SUB-PROCESS.
- 自身を呼び出す代わりに、条件を満たした時のみ処理を行う
ADD 1 TO WS-COUNTER.
DISPLAY ‘現在のカウント: ‘ WS-COUNTER.
IF WS-COUNTER >= 5
MOVE ‘N’ TO WS-LOOP-FLG
END-IF.
- ここで PERFORM SUB-PROCESS を記述してはならない
応用・注意点:現場で生き残るためのテクニック
現場で最も多いミスは、複雑な業務ロジックを組んでいる最中に、うっかりと上位段落をPERFORMしてしまうケースです。これを防ぐためのポイントを挙げます。
1. モジュール分割の徹底: 処理が複雑になり、再帰が必要だと感じたら、それは単一プログラムの限界です。素直にCALL文で外部プログラムを呼び出す設計に変更しましょう。
2. PERFORM THROUGHの危険性: 範囲指定で手続きをまとめる際、意図せず自分自身を包含しないよう注意してください。
3. コードレビューの観点: レビュー時には「この段落から呼び出されている全ての段落が、上位段落を逆参照していないか」を確認するだけで、重大な障害を未然に防ぐことができます。
COBOLは古い言語ですが、その制約は「予測可能性」を高めるための先人の知恵でもあります。基本を疎かにせず、堅牢なシステムを作り上げてください。

コメント