| 著作一覧 |
昨日書いたリストを眺めていて、やっと「トリッキーなコード」という言葉の意味を理解したように思えた。
トリッキーという言葉が意味することは「奇をてらったさま。巧妙なさま。「―な仕組み」」なので、奇をてらってはいるけれど、考え通りに動く=巧妙なコードという意味だろう。
女子高校生風に考える(良くわからないことにしておくが、こういう場合、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;ではないかと。
ううむ、まったく説得力をなくすバグの連続。後で直しておきます。ありがとうございました。
あれ? 更新できたぞ。