do-while(false)の利点は何ですか?
-
22-07-2019 - |
質問
別の従業員によって処理されたコードを調べると、次のように記述された多くのコードが表示されます。
do{
...
}while(false);
これによりどのような利点が得られますか?
コードで発生しているスケルトンの詳細を次に示します。
try{
do{
// Set some variables
for(...) {
if(...) break;
// Do some more stuff
if(...) break;
// Do some more stuff
}
}while(false);
}catch(Exception e) {
// Exception handling
}
更新:
C ++バージョン:
do-while-falseループは一般的ですか
解決
「ループ」から飛び出すことができたのかもしれません。いつでも、例:
do
{
...
if (somethingIsWrong) break;
//more code
...
}
while(false);
しかし、他の人が言ったように、私はこのようにはしません。
他のヒント
Javaでは、これを行う理由はありません。
Cでは、これはマクロを定義するときの一般的なイディオムです。
検討:
#define macro1 doStuff(); doOtherStuff()
#define macro2 do{ doStuff(); doOtherStuff(); } while( false )
if( something ) macro1; // only the first statement in macro1 is executed conditionally
if( something ) macro2; // does what it looks like it does
...しかし、Cのマクロは悪であり、可能な限り避けるべきです。
同僚はCのバックグラウンドから来ていますか?
利点はありません。しないでください。
ブロックの末尾に移動して、if / thenブロックのネストされた束を回避するために使用できます。
do {
if (done()) continue;
// do a bunch of stuff
if (done()) continue;
// do a bunch more stuff
if (done()) continue;
// do even more stuff
} while (false);
これは、マクロ内のブロックを定義するためにCで使用されます。たとえば、これを参照してください。
例、次は無効です:
#define f(x) { g(x); h(x); }
if (x >= 0) f(x); else f(-x);
ただし、この定義では機能します:
#define f(x) do { g(x); h(x) } while(false)
それは役に立たないが、コーダーはいくつかの奇妙な例外処理を行うために複数のブレークコマンドを使用することもできた。
do{
if(<something>){...}else{break}
if(<something else>){...}else{break}
...
}while(false)
その愚かさは認めましたが、古いcプログラムのようなものを一度見つけました
あなたの直感は正しいです。これはまったく役に立たないことです。
それをコーディングした人が元々条件として false
以外のものを持ち、削除するのではなく単に false
に変更したことは可能ですこの「履歴」を失わないためにブロック全体コードの。しかし、これはストローを握っているだけです。率直に言って、これは tautology の単なる例です。コードに配置します。
C / C ++以外のほとんどすべての言語では、これは戦術的な利点を提供しません。
C / C ++では、do / while(false)を使用すると、マクロを安全に複数のステートメントに展開しやすくなるマクロがあります。これは、マクロが通常の関数呼び出しのように見える場合に有利です。
この質問
OPはこの正確な構造について尋ね、それを使用するいくつかの理由を説明します。コンセンサスは、それは悪いことだと思われます。
false
の代わりに他の条件が置かれた場合の将来のプレースホルダーとして。
一部のコード( goto
など)の実行をスキップするために使用できますが、もう一度確認すると、 for
ループ( if(...)break;
ステートメントは) do-while
にあります。それ以外の場合は、Javaバージョンの goto
...
私はこのコンベンションを何年も使用しています! 「パイプライン」がある場合に最も便利です。処理および/または条件チェックの。ネストされたif()ステートメントの複数レベルを単純に回避するため、コードが(はるかに)読みやすくなります。はい、try / catchのような代替手段があり、特定のシン/低レベルの状況でのみこのスタイルを使用します。
「ループ」を開始します; (実際にはループしません)次のようなコメントで...
// Error loop (never loops)
エラーループは...
set errorCode = fail;
do {
if (this)
break;
if (that)
break;
// Success
set errorCode = ok;
// Alternative Success
errorCode = doWhatever();
} while (false);
多数のネストされたif()ステートメントがあり、インデントが3レベルを超える場合、このスタイルを検討してください。
Perl、C / C ++、Java、Delphi / Pascalでこの規則を使用しました。
その作者は自分のコードを信頼していなかったと思うので、数回実行して、それがさらに機能するかどうかを確認しました。これがその遺跡です。
私が考えることができる唯一の理由は、 {...}
内で宣言された変数をより厳密にスコープするブロックを作成することですが、これを行うより良い方法があります(関数の作成、または単にブロックを作成する-Pete Kirkhamへのヒント)。