2011-01-07 9 views
10

のC++外の可能性の重複で:コードは、マクロを定義していないときなぜ使用するか{...} while(FALSE);マクロ

do { 
    // a lot of code that only needs to be run once 
} while (FALSE); 


Are do-while-false loops common?

のようなコードを持っているが理由です?私はそれがマクロになると、それはトリックだが、それは通常のコードでそれの理由はありますか?

+0

私は実際には分かっていませんが、少なくとも「単一反復ループ」から、あなたが必要とするべきであれば、「中断する」ことができます。理論的には、これは大きなネストされた 'if'ステートメントの使用を減らすことができます。 – icabod

+0

@marcog - 主な相違点は、Cに関する質問であると思われます。特に、C++の例外の機能を実装するためにそれらを使用しています。これは明示的にC++の質問(それが該当しない)なので、私はそれらが異なる質問だと思う。 –

答えて

10

何らかの理由で早期終了が必要な場合は、break;(またはcontinue)キーワードを早期終了に使用することができます。それはちょっと醜いだろう。私は実際にはそれが自分自身のルーチンに移行したことを見て、早めの終了はreturn;のステートメントで実装されています。

+1

うーん、それは醜いです。私にとっては、サブルーチンに壊れていることを示しています(今言及したように)。 –

+0

私はあなたに同意します。私は無制限のループが好きではなかった、彼らはちょうど私にぬるぬるようだ:)。 whileの条件でループを終了する評価を置く方が良いでしょう。それがそこにあるのです。他の何もかもは、通常、ちょうど怠惰なプログラミングです。私は怠惰なプログラマのための隠れた/ gotoとして継続しますが、それは私の石鹸です。 :) – SRM

+0

代わりにリターンステートメントを使って早期出口を希望しますか?私が見ているコードの中には、breakステートメントをリターンに置き換えてdo-whileを削除することができるものがあります。それは良いですか? – Anon

2

このような構造体は、breakステートメントを使用してループの終了後にジャンプできるように、gotoの種類として使用されます。

+5

私は他の制御構造を "一種のgoto"と呼ぶファンではありません。 **すべての**制御構造は "一種のgoto"です。類似点ではなく興味深い違いがあります。 –

+1

もちろん、すべての制御構造はマシンレベルではgotoですが、言語レベルでは 'goto'は' goto'文であり、 'if'文ではありません。 –

0

goto文と同様の動作を実装するために使用することができます。ジャンプのような動作が可能です。

do 
{  
    if (doSomething() != 0) break; //jump 
    if (doSomethingElse() != 0) break; //jump 
    ... 
    if (doSomethingElseNew() != 0) break; //jump 
} while(false); 

//if any of the break encountered, execution can continue from here, just after the do-while block! 

// statement1 
// statement2 
// statement3 
// so on 

ここから撮影:

が、これは参照してくださいあなたはいくつかの点で抜け出すしたい場合は、それについてAre do-while-false loops common?

3

まあ一つの理由は次のようになります。特定の状況で

すなわち

do 
{ 
    //some code that should always execute... 

    if (condition) 
    { 
     //do some stuff 
     break; 
    } 

    //some code that should execute if condition is not true 

    if (condition2) 
    { 
     //do some more stuff 
     break; 
    } 

    //further code that should not execute if condition or condition2 are true 

} 
while(false); 

結果のコードは、上記のように書かれた場合に理解しやすい/もう少し明らかです。

+6

これよりも常に明確なことが分かり、不要なブロックは導入されません。 'goto'。 –

+0

@Steve M - 実際に同意します。しかし、IMHOには独自のルーチンを正当化するコードがたくさんあります。あなたがそうするならば、代わりに 'return'を使うことができます。これは、' goto'よりも少し制御されておらず、独断的な開発者からそのような空想的な応答を引き出しません。 –

2

私はこれを行うにはなくなります

を私はちょうど

int main() 
{ 
    { 
     std::ifstream file("Data"); 
     // DO STUFF 

    } // Data now closed. 

    // LOTS OF STUFF SO YOU CANT SEE file2 below. 

    // We can re-use data here as it was closed. 
    std::ofstream file2("Data"); 
    // DO STUFF 
} 

unobservantメンテナがブレースを見ると思うかもしれブレースよりも、もう少し論理的に見えます。
一体何と彼らに

int main() 
{ 
    std::ifstream file("Data"); 
    // DO STUFF 

    // LOTS OF STUFF SO YOU CANT SEE file2 below. 

    // FAIL. data is still open from before. 
    std::ofstream file2("Data"); 
    // DO STUFF 
} 

を削除し、私は(unobservantメンテナはまだそれを削除するかもしれませんが)しばらくティックを使用すると、少なくともsyouはそれについて考えさせると仮定します。

int main() 
{ 
    do 
    { 
     std::ifstream file("Data"); 
     // DO STUFF 

    } while (false); 

    // LOTS OF STUFF SO YOU CANT SEE file2 below. 

    // We can re-use data here as it was closed. 
    std::ofstream file2("Data"); 
    // DO STUFF 
} 
1

コンパイル時に、正確に1回実行されることが知られているループを作成する理由はありません。

これを行うには、gotobreakと書かれていますが、それは不正です。

EDIT:

私はちょうど私の主張についてコンパイル時の知識が偽であることに気づきました:私はあなたが1つのビルド構成のためのコンパイル時に、以下のことを意味するかもしれない条件の#defineで複雑な何かをするかもしれないと仮定し、一度実行することは知られていますが、別のビルド構成では複数回実行されます。

#ifdef SOMETHING 
#define CONDITION (--x) 
#else 
#define CONDITION 0 
#endif 
... 
int x = 5 
do{ 
    ... 
} while(CONDITION) 

しかし、私のアサーションの精神は依然として立っています。

+0

+1。 'do while(false)'は、インライン関数をシミュレートするマクロの外では恐ろしい反イディオムです(これは、彼ら自身の恐ろしいブランドです)。また、実際のコードで '#define 'のようなものが見えたら、私は外に出ます。 –

+0

ええ、 '#define'はやや狂った例ですが、IRLを使うための正当性を思いつくことはできません。私はちょうど私にプリコンパイラの教訓を与えてくれるペダントはほしくありませんでした。 –

関連する問題