プログラマー歴20年ですが goto がどんなに有用なのか聞いてほしい
こんばんは。
ちまたの新入社員教育では「goto を使うとプログラムが汚くなるから使用禁止ね」と教えられ、会社では goto の入ったコードは忌み嫌わせているようです。自分も20年くらい前に入社した会社でそのように教えられた記憶があります。しかしいまいち納得がいかないまま今に至っています。
以下に、自分が知る限り「goto を使ってよかった!」「goto を使ったら彼女ができました!」「gotoを使い始めてからパチンコも勝ちまくりです!」といった事例をあげていきたいと思います。例によって反論は歓迎しますので、一緒に正しい結論にたどり着きましょう!
なお、言語は限定しませんが、C/C++ での例をあげていきます。
Contents
多重 for ループからの脱出に有用
まずは1番わかりやすい例です。普通の for ループだと、break で抜け出すことができますが、for がネストした2重以上のループの途中で、その一番外のループから抜け出したい場合、どうしたらよいでしょうか?goto を使うと美しく記述できます。
goto を使わない場合、そのためのフラグを用意する必要が出てきます。 これは goto をつかった記述とどちらが美しいですかね?
エラー検知時の処理に有用
次に外部システムとのやりとりを行う関数中でのエラー処理を考えてみましょう。一連の処理の途中、復旧不能なエラーに遭遇し、処理をあきらめる場合に goto が便利です。
gotoを使わない記述では、フラグを用意するくらいしか思いつきません。やはり goto のパワフルさが際立つ一例です。
[※2015年9月7日 @ooee81 さんのご指摘に従い、return では実現できない例になるよう、エラー発生後に共通の処理を追加しました。]
ユーザー対話式処理の記述に有用
アクションゲームではあまり必要になりませんが、ユーザーの入力にしたがってシナリオを進めていくようなRPGのような処理を記述する場合、goto が欲しくなりますよ。
ユーザーがキャンセルしたときに、1つ前の選択画面に戻る必要があると思いますが(この例では、攻撃を選択した後、攻撃方法の選択でキャンセルした場合)それってgotoを使う記述がもっとも適していると思うんですよ。
例外でも似たようなことできるんじゃないですか?
場合によってはできます。しかし例外は関数を飛び越えられるので危険です。特にC++ではメモリリークの元。まあガーベージコレクションのある処理系(例:Java)なら例外でもいい場合もあります。
Linuxの作者も goto が大好き!
「そんなこと言ってるのはあなたくらいじゃないですか?」と言われそうなので、goto大好きな有名人を紹介します。泣く子もだまるLinuxカーネルの開発者リーナス・トーバルズさんです。
2015年9月7日現在最新のLinux カーネルのソースコードの一部をみてみましょう。
goto がいっぱい!\(^o^)/
https://github.com/torvalds/linux/blob/master/kernel/signal.c
別に彼が goto を使っているから使っていいんだと言うつもりはありませんが、世界的なプログラマーが世界中で使われているコードの中で goto を多用しているという事実は興味深いと思って紹介しました。
まとめ
Linux 開発者のリーナス・トーバルズは goto 大好きらしいです。
そうは言っても、使い方を間違えると、わかりにくいプログラムを生み出す元になるのはご存知の通りですので、むやみに使うべきではありません。
というわけで嫌われ者の goto ですが、言語によっては(特にC/C++)時として有用だと思います。