著作一覧 |
昨日書いたリストを眺めていて、やっと「トリッキーなコード」という言葉の意味を理解したように思えた。
トリッキーという言葉が意味することは「奇をてらったさま。巧妙なさま。「―な仕組み」」なので、奇をてらってはいるけれど、考え通りに動く=巧妙なコードという意味だろう。
女子高校生風に考える(良くわからないことにしておくが、こういう場合、JKと書くものらしい)と、途中のコードをスキップして制御を移動させる場合はgotoというステートメントを使うものだ。Cの言語仕様ではそうなっている。
したがって、常識的で、まったく奇のてらいがない、普通のコードであれば
int foo() { int result = ERROR_EXIT; if (foobar() != SUCCESS) goto error_return; if (barbaz() != SUCCESS) goto error_return; ... ... result = SUCCESS; error_return: return result; }
と書くところだ。
これは、しかし、do……whileを使った(修正済み:コメント欄参照)トリッキーなコードでも記述できる。
int foo() { int result = ERROR_EXIT; do { if (foobar() != SUCCESS) break; if (barbaz() != SUCCESS) break; ... result = SUCCESS; } while (0); return result; }
これがトリッキーなのは、本来、「偽になるまでループ」するために利用するwhileを、breakによって節から退出できることを悪用してgotoに代替させている点にある。そもそも論では、あらかじめ条件式に偽を設定するところからしてトリッキーだ。
僕が良く耳にする女子高校生なコーディング規約は、「トリッキーなコードは禁止」というものだ。ふむ。
どうやら、トリッキーなコードを許容できるくらいに、gotoを使うことに無意味(この場合に意味ありますか?)な拒否反応があるのだろう。
おもしろい。
そこで考えるのだが、ダイクストラの時代であればともかく、while、do……while、さらにはforといった至極便利極まりないステートメントを持つ言語を利用していて、あえてgotoを使う人がいるのだろうか?
昔の人はそうだったかも知れない。はじめてwhileだのdoだのを目にした人が、「かーっ! こんなまだるっこしいもの使ってられるかってんだ」とgotoを使うというのは、まあ、理解できなくはない。
しかしだよ、今この時点で、
for (int i = 0; i < 10; i++) { if (a) { continue; } else if (b) { break; } ... }
と書かずに、わざわざわざと、
int i = 0; start_loop: if (i >= 10) goto exit_loop; if (a) { i++; goto start_loop; } else if (b) { goto exit_loop; } .... i++; goto start_loop; exit_loop: ...
なんて書くかね? 本気でそう信じているのか?
そう信じているなら、イワシの頭賞を進呈する。どうぞご自由に。
しかし、女子高校生風に考えれば、そんな面倒なことをする人間はいない。
であれば、goto禁止というのは取り下げたほうが良い。
そうすれば、「このgotoというステートメントは何の役に立つんだ?」となるだろう。
そこで、「エラーになったら、エラーリターン用のラベルへ分岐するために利用したり、深い制御構造の中から脱出するために利用するんだよ」で済むではないか。
10年ドロドロおじさんの悪口を言うのも結構だが、ドロドロおじさんと同じレベルで「禁止」とか無定見に言ってないか、考えてみても良いと思う。
ジェズイットを見習え |
while(0) じゃ通らないっす.do/while(0) かな,とは思うんですが.
ははは。本当ですね。直しました。どうもありがとうございます。
しまった。このくらいトリッキーなコードは危険だ、とかなんとか入れておくべきだった。
便乗してどうでもいいツッコミですが、next;じゃなくて<br>continue;ではないかと。
ううむ、まったく説得力をなくすバグの連続。後で直しておきます。ありがとうございました。
あれ? 更新できたぞ。