ものがたり(旧)

atsushieno.hatenablog.com に続く

goto heaven / goto hell

人はいかにgoto文を[使わない|使う]か。見た感じ、あまり意外ではないし、実に妥当な結論(?)に見える。gotoについてどう思う?という質問はひとつの試金石だし。

Ximianで最適化を試行錯誤するまでの僕は、gotoはほとんど使わなかったのだけど、gotoを使う場面というものに何となく憧れていた節がある。そしてmscorlibやmcsのソースなどをいじるようになると、たちまちgotoの嵐。パッチを作ればgotoじゃなきゃ嫌だと言われるような世界だ。このケースみたいに、別の関数を作って呼び出すなんてパフォーマンス的に論外な状況は多々ある。

一般的には、gotoは低レベルプログラミングに親和的で、デザインパターンがどうのSOAがどうのっていう世界ではあまり使われない。こういう人たちは、パフォーマンスをプログラム設計のレベルで問う機会が少ないだろうし、むしろ設計の障害となる構造化指向の破壊*1を気にするので、gotoは使わない、という傾向が強いだろう。

ただ、僕の印象としては、C#におけるgotoの禁忌度(変な表現だけど)は、CとかC++のそれよりも小さいのではないかと思う。ひとつにはフロー・コントロールが言語レベルで確立していること(C#言語仕様で最初から明記されている)。未初期化変数はコンパイラによってかなり厳密にチェックされる*2。finallyの存在によって、複数ラベル式が必要になる場面はほとんど無い。フロー・コントロールが確立しているので、(JITを含む)コンパイラが最適化を放棄することも無い。

ちなみにMonoでは、フローを分断するcontinueはLinus Torvaldsトリックとしてむしろ推奨されている。ガード節(と言うの?僕は経験浅いんでよく知らないんだけど)もそうだ。契約上特定の入力にはnullを返さなければならない時、それ以外の条件をelseでくくってあとは延々インデントが1ネスト深いコードが続くのって、ストレス溜まるし。

*1:もちろん、関数単位では出入り口一つの原則が維持されていることは理解している。だけどそれがリファクタリングにとって無用な制約になることも確かだ。

*2:その意味ではこの辺にバグをいくつか抱えていたmcsでgotoを使いまくっていたXimianハッカーは比較的クレイジー