1. なぜ「計算型GOTO」の挙動理解が重要なのか
数値計算の世界では、古いFORTRAN資産(F77など)を現代の解析コードに組み込む機会が依然として存在します。その中で最も危険なレガシー機能の一つが「計算型GOTO」です。この文は、インデックスが範囲外になった際にエラーを出さず、そのまま次の行へ処理を流すという挙動をとります。これは一見、柔軟な制御のように見えますが、実際には計算結果が異常値であることに気づかずプログラムが続行される「サイレント・フェイル」を引き起こす最大の要因です。
2. 基礎知識:計算型GOTOとは何か
計算型GOTOは、`GOTO (ラベル1, ラベル2, …), 変数I` という形式で記述されます。これは変数`I`の値が1ならラベル1へ、2ならラベル2へ……というように、条件分岐を行う仕組みです。現代のプログラムであれば `SELECT CASE` 文を使うべき場面ですが、古いコードでは頻繁に現れます。ここで重要なのは、「範囲外のインデックス」に対する標準的なエラーチェックが存在しないという設計思想です。
3. 実装と解決策:安全な代替手段への置換
計算型GOTOのインデックス範囲外挙動は、仕様上「何もしないで次の文へ進む(フォールスルー)」と定められています。開発者が「この変数は必ず1〜2の範囲に収まるはずだ」と信じていても、バグや予期せぬ入力で`I=3`となった瞬間、プログラムは意図しないパスへ進みます。解決策は簡単です。計算型GOTOを一切使わず、`SELECT CASE` 文に書き換えることで、`CASE DEFAULT` を用いた明示的なエラーハンドリングが可能になります。
4. サンプルプログラム
以下のコードは、計算型GOTOの危険な挙動と、それを安全な `SELECT CASE` に書き換える比較例です。
! --- 危険な実装例 ---
! Iが3の場合、何もせず下の行へ進んでしまう
GOTO (100, 200), I
! ここで意図しない計算が実行されるリスクがある
PRINT , "予期せぬ処理が実行されました!"
STOP
100 CONTINUE
! 処理A
GOTO 300
200 CONTINUE
! 処理B
GOTO 300
300 CONTINUE
! --- 安全な実装例 (推奨) ---
SELECT CASE (I)
CASE (1)
! 処理A
CASE (2)
! 処理B
CASE DEFAULT
! ここでエラーハンドリングを強制する
PRINT , "エラー: インデックスが範囲外です"
STOP
END SELECT
5. 応用・注意点:現場でのバグ回避
現場でレガシーコードを保守する際、「計算型GOTO」を見つけたら、まずはその直前にインデックス範囲チェックを入れることが鉄則です。もし書き換えが困難な大規模プロジェクトであれば、必ず以下のようなガード文を挿入してください。
if (i < 1 .or. i > n) stop ‘致命的エラー: 計算型GOTOの範囲外アクセス’
この一行があるだけで、サイレント・フェイルによる誤った計算結果の出力(非物理的な値の生成など)を未然に防ぐことができます。古い機能の互換性は重要ですが、数値計算においては「正確性」が最優先であることを忘れないでください。

コメント