2006年03月23日

gotoは絶対悪か?

プログラムという事に携わっていると必ずある
「goto」の論争。

大抵の言語ではgotoが必要な状況がほとんど無い。
(アセンブラは除く、つか無理)
最近の言語では例外処理もできるので、goto(無条件ジャンプ)
しなくてはならない状況が無いというものだ。
案件によってはコーディングガイド等でgotoが禁止されているものもあるだろう。

gotoは本当に絶対悪なのだろうか?
旧世代のCOBOL資産からJavaや、C#へのマイグレーション案件で
もっとも困るのがこのgoto文。
最近の言語しか知らない新人等は制御が追い切れず、戸惑っていることも
しばしばだ。

確かに、処理の流れ上、一方通行でない分岐にgotoが使われている
非常に理解に苦しむ。グローバル変数と並んで、絶対悪とされているのも
うなずける。4000行とかのCOBOLソースで、gotoが乱発されていると
読む気が失せる。
(書いた人を逆に尊敬してしまう。)

かといって、必ずしも全てのgotoが悪である、とは私は思わない。
一方通行で、集約された流れで有れば問題ないのでは無いだろうか。

例えば、例外機構の無い言語において、エラー処理は悩みの種である。

if エラーチェック then
  エラーメッセージ処理
  return エラーコード
end if


この様な処理はエラーチェックが一つであれば問題無いが、大抵は
複数のエラーチェックが必要だ。

これが3つになった場合
if エラーチェック1 then
  エラーメッセージ処理
  return エラーコード
end if
if エラーチェック2 then
  エラーメッセージ処理
  return エラーコード
end if
if エラーチェック3 then
  エラーメッセージ処理
  return エラーコード
end if


と同じようなコードが続いてしまう。
エラー処理が共通化できない。
この処理にgotoを適用してみると

if エラーチェック then
  メッセージID、エラーコードのセット
  goto エラー処理
end if

エラー処理:
 メッセージ表示 
 return エラーコード


とエラー処理を集約できる。
javaやC#でいうところのcatch句を作ってしまおうというわけだ
これにより、例えば「エラー時には回線を切断すること」というような
仕様書で書けば一文の仕様変更に対して、コードの修正量も大幅に減らせる。
gotoを使わない例の場合、各エラー毎に処理を組み込まねばならないからだ。
変更量が多いということはすなわち、unitテストに対する評価量も増え、
作業量が増えてしまう。

エラー時に即リターンできるような場合だと呼び出し元で実装することで
同意になるが、大抵の場合、即リターンできない。
エラー処理がループのネストに入っていると、後始末が大変である。

よって、私の考えは
「gotoは基本的に悪。その他のベストチョイスが有れば使うべきではない。
 ただし、一方通行の流れで且つ、goto以外に最適解が見つからない場合、
 正しくgotoの意味を理解できるプログラマが使用する分には、
 例外的に使用してもよい。」

である。
賛否両論はあるだろうが…

posted by koteitan at 18:26| Comment(0) | TrackBack(0) | プログラム全般 | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
この記事へのトラックバックURL
http://blog.seesaa.jp/tb/15347226

この記事へのトラックバック