do {} while (0)
http://d.hatena.ne.jp/puruhime/20071118#1195318276
http://d.hatena.ne.jp/Isoparametric/20071113/1194905094
否定的な意見が多いみたいですけど、個人的には気に入っていて結構使うので、if(){}else{}にくらべて良いケースを。
あるコードで、複数の条件がすべて満たされないと実行しない処理があるとします。んで、その一つ一つの条件判定が数行ずつ掛かるとしましょう。
これが関数のトップレベルの場合、
result_type function(...) { // 条件Aの判定準備コード ... // 結果がcond_Aに入る if (! cond_A) return ERROR; // 条件Bの判定準備コード ... // 結果がcond_Bに入る if (! cond_B) return ERROR; ... // 条件Zの判定準備コード ... // 結果がcond_Zに入る if (! cond_Z) return ERROR; // ある処理の本体 ... }
と掛けますが、トップレベルでない場合、つまり、この「ある処理」の後に、ある処理の実行の有無と関係なく評価されるコードがある場合には、
{ // 条件Aの判定準備コード ... // 結果がcond_Aに入る if (cond_A) { // 条件Bの判定準備コード ... // 結果がcond_Bに入る if (cond_B) { ... // 条件Zの判定準備コード ... // 結果がcond_Zに入る if (cond_Z) { // ある処理の本体 ... } ... } } }
のようになって、ネストが深くなります。
一方、do {} while(0)なら
do { // 条件Aの判定準備コード ... // 結果がcond_Aに入る if (! cond_A) break; // 条件Bの判定準備コード ... // 結果がcond_Bに入る if (! cond_B) break; ... // 条件Zの判定準備コード ... // 結果がcond_Zに入る if (! cond_Z) break; // ある処理の本体 ... }
と書けます。
もちろん、gotoで脱出すれば良いんですけどね。
…いやなんか昔、gotoだとブロック脱出時にデストラクタが上手く動かないと信じていた時期があって、その影響なんですが。
…あれ?動きますよね、デストラクタ?gotoでも?