ma2のblog - わんくま版(仮)

うどん、より、そば

目次

Blog 利用状況

ニュース

Xbox360ゲーマータグ

リンク

書庫

日記カテゴリ

カラwhileって使いますか?

VSS で管理しているのにソースの修正部分の差分をコメントとして残す(じゃんぬねっと日誌)を見て思い出したことがあります。

関数の中にreturnを複数書いてはいけない、というルールはよく見かけます。
拒絶反応を起こす人もよく見ます。自分もそうです。
インデントが深くなるのは見辛くて駄目だ。こんなのナシだ!! とルールに立ち向かう人がいました。
ここではレジスタンスと呼ぶことにします。
レジスタンスもたくさんいるわけですが、その中でも感動した方法は次のものです。

BOOL func( void )
{
  BOOL bRet = FALSE;

  while( 1 ){
    if( !test1() ){
      break;
    }
    if( !test2() ){
      break;
    }
    if( !test3() ){
      break;
    }
    if( !test4() ){
      break;
    }
    if( !test5() ){
      break;
    }
    testOKfunc();  // 条件を満たせばできる処理
    bRet = TRUE;
    break;
  }
  return bRet;
}

ガード句を使いながら、returnはひとつだけです。
このような書き方を "カラwhile" と呼んでいました。whileの最後でbreakする(=ループしない)からだと思います。
もちろん別の戦地ではこんな言葉通じません。

この方法が良いか悪いかの判断ができなかったのと、returnの代わりにbreakを書く習慣がなかった(書き忘れると怖い)ので自分は使いませんでしたが。

# やっと抱負に挙げた方面のネタが書けました

投稿日時 : 2008年6月5日 1:36

コメントを追加

# re: カラwhileって使いますか? 2008/06/05 1:57 尾画茶@やっぱり異端者だった

そうだったのですか……。return は1つにすべきだったのですか。
だから、サンプルコードなどでは、大抵そういう書き方にしてあったんですね。今、納得しました。
ずっと私は、「処理を抜けたい奴は、とっとと帰れ!」とreturn で追い払っていました。
でも、強制されるまで、レジスタンスでいたいな。

# re: カラwhileって使いますか? 2008/06/05 2:17 出水

禁止、禁止だけ言って推奨手段を提示しないから
こういうトリッキーで可読性に劣るコードが出来るんだと思います。
こんなことやるならgoto使ったほうがまだましです。

ソースの保守性を高めるのが目的なのに低くしてどうするのかと…
まともなコードもかけない人で手一杯なのに、
少なくともちゃんとしたコードを知っている人まで敵に回したら
どうにもならないと思うんですね

# re: カラwhileって使いますか? 2008/06/05 8:02 あんどちん

こういうときは、do~while(0)を使うな。
どっちにしても読みにくくなることに変わりはないけど。

# re: カラwhileって使いますか? 2008/06/05 8:30 st.lain

Blogに別途書こうかと思いましたが、書かれたので
コメント便乗しちゃいます。(w

# そもそもガード句ということ自体を知らなかったので
# 論点がズレてるカモしれません。

try~catchで自らスローして自らキャッチとか、
出来ないのカナ。
(例外使い方知らないので、これを気に勉強しなきゃ・・)

私的に、whileのような繰り返しを「主」目的とした構文で
あるにも関わらず1度しかさせないようにしたような、
相反する部分がちょっと気にかかります。

> 書き忘れると怖い
やはり、私はこれに尽きると思います。

> 関数の中にreturnを複数書いてはいけない、というルール
VB系ってon error gotoを使えば当然(?)、Exit Sub
なりExit Functionが出てくると思うのですが、ある意味、
複数returnを行ってるのと(広義で)同義な気がします。

そゆのは大丈夫なのカナ・・・とか思ったりするところです。

# re: カラwhileって使いますか? 2008/06/05 8:34 st.lain

書いてから思ったこと。自分のカキコの

> VB系って
の話は無かったことに・・・。比較土台として不適切な
ように思えてきました。 orz

# re: カラwhileって使いますか? 2008/06/05 9:13 Hirotow

はじめこれ見たとき意味不明で、
教えてもらったとき軽く感動しました。
ちなみにうちはwhile-true-breakよりdo-while-falseのほうが多いかも。

# re: カラwhileって使いますか? 2008/06/05 9:14 Hirotow

default:
return;
で異常引数な処理をスキップできるのに。

# re: カラwhileって使いますか? 2008/06/05 9:18 じゃんぬねっと

昔の VB には continue がなかったので空の Do ~ While で代用しているソースなんてありますね。
素直に GoTo Continue と書いた方がわかりやすい。

# re: カラwhileって使いますか? 2008/06/05 9:24 じゃんぬねっと

> try~catchで自らスローして自らキャッチとか、
> 出来ないのカナ。
コストが高く挙動にさえ関わるので使ってはいけません。

> 私的に、whileのような繰り返しを「主」目的とした構文で
> あるにも関わらず1度しかさせないようにしたような、
> 相反する部分がちょっと気にかかります。
条件によっては 1 回で済むので回数の問題というよりは、"ブロックを作りたい" という目的に違和感を感じるのだと思います。

> VB系ってon error gotoを使えば当然(?)、Exit Sub
> なりExit Functionが出てくると思うのですが、ある意味、
> 複数returnを行ってるのと(広義で)同義な気がします。
> そゆのは大丈夫なのカナ・・・とか思ったりするところです。
VB の Exit Sub, Exit Function は、戻り値を返さない return に相当します (Exit Sub はモロにそうだし、Exit Function も戻り値をその前に別途格納しているので同じです) からルールがあるならやってはいけないことになります。

# re: カラwhileって使いますか? 2008/06/05 9:34 st.lain

> コストが高く
そっか、そうですよね・・・。コストは考えていませんでした orz

# re: カラwhileって使いますか? 2008/06/05 10:23 ぽぴ王子

最初に手がけた Delphi のプロジェクトで多用されていました。
実際のところ自分ではなくリーダーが発案者だったです。

気持ちはわかるし、使うこともやぶさかではありません。
(可読性というのを抜きにすれば)

でも今はなんとなく使ってないんですよね。なんでだろ。
それが必要な場面がないからだと思います。単についてるだけかも。
もしもそういった場面になったら、goto とどちらを使うかと
考えると、やはり while にしてしまいそうです。
あ、でもやるとしたらキッチリコメント書きますね。
(逆にコメントを書くということは可読性が低いということでもあるわけですが)

これに関しては、自分の中での正解はまだ出せていない状況です。
どうも無意識のうちにこのパターンを避けているような気がします。

# re: カラwhileって使いますか? 2008/06/05 12:18 渋木宏明(ひどり)

ループ脱出と関数からの戻りの「あるべき」論がごっちゃになってる希ガス。

メソッド内での return の濫用は、「必要な終了処理が行われないままメソッドから抜けてしまう」可能性があるので、好きではありません>じぶん

じゃあ goto 使えばいいじゃんて話もありますが、宗教上の理由からそれも避けています>じぶん

ですが、C# では try ~ finally が使えるので、宗教上の禁忌を冒してまで goto を使うべきか?と悩むことはなくなりました。

# [.NET]おっさんホイホイとしての Code Complete と,近くにあっても気付かない guard 句の話 2008/06/05 13:50 NyaRuRuの日記

VSS で管理しているのにソースの修正部分の差分をコメントとして残す - じゃんぬねっと日誌 カラwhileって使いますか? - ma2のblog - わんくま版(仮) 正常系が先か異常系が先かという問題 - Hirotow’s Craftive Blogs ガード句かぁ,じゃんぬねっとさんは『Code Complete

# [C++]日本ブレイクコード 2008/06/05 19:53 Garbage Collection

[C++]日本ブレイクコード

# リターンは一度だけ 2008/06/05 22:12 組み込まれない組み込み屋

リターンは一度だけ

# re: カラwhileって使いますか? 2008/06/06 0:58 ma2

こんなにコメントがつくとは。
申し訳ないですが、ポイントを絞ってレスします。

> そうだったのですか
いくつもあるポリシーの内のひとつなので、ガード句で止めるやり方がダメというわけではないと思います。

> 推奨手段
確かに代替するパターンって見かけないですね。

> 例外
いろいろあって例外を使わなかったり(理解できてる人員の都合)、使えなかったり(純粋なC言語とか)するのです。
# 「私個人が使ってみたところ、意味側からなったので」って理由で例外の使用を禁止してるところもありました(前置きとして規約書に書いてあった)

> gotoとwhile
> 宗教上の理由
gotoの4文字で何人の血が流れることか・・・。使いたくないですよね。わかります。

> do-while-false
あれ? ミスが防げるのにうれしくない。なんでだろう。

タイトル  
名前  
URL
コメント