gotoは、多くのプログラミング言語におけるステートメントです。英語のgotoを組み合わせた造語です。コードの別の行にジャンプするための方法です。

多くの言語がgoto文をサポートしていますが、サポートしていない言語もあります。Javaでは、gotoは予約語ですが、使うことはできません。(予約語とは、プログラミング言語の一部であり、変数の命名など他のことには使用できない単語です)

コンピュータサイエンスには「構造化プログラム定理」という理論があります。これは、どんなプログラムでも、非常に大きなプログラムやgoto文ではなく、関数やメソッド(小さなサブプログラム)を使って物事を行うように書くことができるという理論です。この理論は、プログラムを書くのにgoto文は必要ないことを証明しています。

goto の定義と基本的な考え方

gotoは、プログラムの実行位置(命令ポインタ)をラベルで指定した別の位置に移す命令です。ラベルは通常、コード中の目印となる名前で、そこへジャンプするとその行から処理が続きます。直線的な手続き型コードの途中で任意の場所へ飛べるため、柔軟ですが同時に誤用すると可読性や保守性が落ちます。

使い方と構文(例)

言語ごとに構文は異なりますが、典型的な C の例は次の通りです。

int main() {     int i = 0; start:     if (i < 5) {         printf("%d\n", i);         i++;         goto start;     }     return 0; }

ラベル(上の例では start)を宣言し、goto start; でそこへジャンプします。

よくある用途

  • 低レベルな言語や古いコードでの分岐処理。
  • C言語などでエラー発生時に共通の後処理(リソース解放)へ飛ぶためのパターン(いわゆる cleanup パターン)。
  • コンパイラや自動生成コードでの効率的な遷移実装(状態遷移など)。

サポートする言語と制限

  • サポートする代表的な言語:C、C++、C#(制限あり)、Go、Perl、PHP、Fortran、アセンブリ言語など。
  • サポートしない/限定的な言語:Javaでは予約語だが使用不可。PythonやJavaScript、Rubyなどの高級言語では一般に goto は存在しない(サードパーティのモジュールやトリックを除く)。
  • 多くの言語はスコープや初期化を壊さないように goto に制限を設けています(例えば、あるブロックの初期化済み変数を飛び越えてジャンプすることを禁止するなど)。

メリットとデメリット

  • メリット
    • 単純なジャンプが直接書けるため、特定の場面(エラー処理の共通後処理、低レイヤの最適化コード)ではコードが短く明快になることがある。
    • 生成コードや状態遷移の実装で効率的に使える。
  • デメリット
    • 乱用すると「スパゲッティコード」と呼ばれる読みづらい構造になりやすい。
    • プログラムの流れが直感的でなくなり、バグや保守性の低下を招く。
    • 正式手法や自動解析、証明を行う際に障害になる場合がある。

構造化プログラミングとの関係と代替手段

冒頭で触れた「構造化プログラム定理」により、gotoを使わなくても、ループ(for/while)、条件分岐(if/else)、関数(サブルーチン)だけで任意の計算は表現できます。現代のプログラミングでは次の代替がよく使われます。

  • ループ(for / while)と break / continue
  • 関数/メソッドによる処理の分割
  • 例外(Exception)やエラーハンドリングの仕組み
  • 構造化された状態遷移(ステートマシンライブラリ等)

実務的なアドバイス — いつ使うべきか

  • 一般的には避ける:読みやすさと保守性の観点から、まずは構造化された代替手段を検討してください。
  • 例外的に許容されるケース:C のようにリソース解放を単一箇所で行うための cleanup 用ラベル、あるいは自動生成コードやかなり低レベルで明確に管理された場面。
  • コードレビューやチームのコーディング規約で使用を明確に制限・許可することをおすすめします。

C におけるよくあるパターン(比較)

cleanup に goto を使う例:

int f() {     resource *r = acquire();     if (!r) return -1;     if (step1() < 0) goto error;     if (step2() < 0) goto error;     release(r);     return 0; error:     release(r);     return -1; }

上記はエラー時の後片付けを一箇所にまとめるために使われます。C++ では RAII(資源獲得は初期化)を使えば、例外やスコープ終了で自動的に開放できるため、goto は不要になります。

まとめ

gotoは強力だが乱用すると可読性・保守性を損なう命令です。構造化プログラミングの考え方からは原則不要とされ、現代の多くの言語や開発現場では使用を避けるべきとされています。一方で、低レベルのエラー処理や自動生成コードでは実用的な場面も残っており、状況に応じて慎重に使うことが重要です。