2011-09-16 8 views
5

ステータスコードを表すintを返すCまたはC++関数を記述するためのベストプラクティスは何ですか?CまたはC++戻り状況

具体的には、クライアントの使用方法について知りたいが、他のヒントを歓迎します。例えば

は、私はこのような何か書くことができます。

int foo() { 
    return 0; // because everything was cool 
} 

をし、このようにそれを使うのか?

if (foo()) { 
    // what to do if false, e.g. non-zero, e.g. not OK 
} else { 
    // what to do if true, e.g. zero, e.g. OK 
} 

のベストプラクティスは、一般的に0のステータスコードはすべてがOKだったとも0はブール文でfalseを意味を意味することを指示するので、これは動作するはずです。

しかし、これは正しい、良いではないでしょう。

if (!foo()) { 
    // what to do if true 
} else { 
    // what to do if false 
} 
+9

ブールステートメントで '0'は' true'を意味しません。 – Chad

+1

C++では、このようなコーディングスタイルを排除するように設計された例外処理を検討することができます。 – templatetypedef

+0

@Chad:彼はそれを認識しているようだ –

答えて

9

は私が働く場所gccはそれを嫌う)。

C++の場合、例外がある場合はそれを使用します(そうでない場合は上記を参照)。

編集: 成功した場合は0を返し、それ以外の場合はエラーを返すことをおすすめします。これは、UNIXのコマンドラインユーティリティが行うものです。

+0

//それにアーケードドンも病気です。 :-) –

+6

私は** reason **を追加します。成功すると0を返し、エラーが発生したときは0以外の値を返します(ブール値1/0がtrue/falseを意味するのに対して)。通常、操作が失敗する理由はたくさんあります成功の唯一のタイプです。 –

+2

それ自体は問題ではありません。 0の意味は、プログラマが怠惰であり、これにより簡潔な 'if(foo())'が動作することが可能になるということです。成功は42と同じくらい簡単にでき、 'if(foo()!= 42)'と書くことができます。 –

1

リターンステータスは、あなたのインターフェイスで定義され、呼び出し側に知られている必要があります。エラーが発生した場合は0を返します(!で確認するのは簡単です)。成功した場合は0が返されます(enumのエラーコードがあり、OKが最初の項目です)。

法律や標準はありません。各インターフェイスには独自の規則が定義されています。 C++では - 例外を使用します。

int err = foo(); 
if (err) { 
    // armageddon 
} 

割り当てと組み合わせることができれば、より多くの複雑な機能とそれがさらに混乱取得し、一部の人々は、条件付きで割り当てによって混乱している呼び出します(と:私たちはCでこれを使用

-2
int foo() { 
    try{ 
    ... 
    return 1 
    } 
    catch 
    { 
    return 0; // because everything was cool 
    } 
} 

try/catchブロックですべてをラップすることから始めます。また、intを使用する代わりに、より多くのシーンを作成してブール値を返すこともできます。これは、ifステートメントでテストするときには少し直感的です。

+0

嚥下の例外はさまざまな理由で悪いことです:http://www.google.com.ar/search? sourceid = chrome&ie = UTF-8&q =嚥下+例外 –

1

ベストプラクティスは、自分自身と他の人がエラーチェックの際に返されるコードをすばやく検索できるように、コードを文書化することです。

5

あなたが本当にステータスコードの意思を記述#define文のenumまたはブロックでそれらを使用する方法、ステータスコードを使用したい場合。例えば

enum 
{ 
    kSuccess = 0, 
    kFailure = -1, 
} 

function foo() 
{ 
    return kSuccess; 
} 

if (kSuccess == foo()) 
{ 
    // Handle successful call to foo 
} 
else 
{ 
    // Handle failed call to foo 
} 

この方法で、意図が明確であり、誰かが将来的にあなたのコードを使用したり、維持したいエラーを起こしやすい当て推量はありません。

+0

「k」とはどういう意味ですか? –

+0

これは単なるスタイルのもので、変数や他の識別子から一定の値が目立つようにするために使用されます。 – adpalumbo

+0

@adpalumbo:しかし、なぜ彼らは目立つ必要がありますか?:) – GManNickG

0

ちょうどあなたの状況で適切な場合があり、別のオプションを使用してボード上のジャンプ:

enum fooret { GOOD, BAD, UGLY, WORSE }; 

fooret foo(); // defined elsewhere 

switch(foo()) 
{ 
case BAD: 
case UGLY: 
    // maybe a recoverable failure(s)... 
    // take appropriate actions 
    break; 
case WORSE: 
    // maybe non-recoverable 
    break; 
case GOOD: 
    // successful, take appropriate actions 
    break; 
} 
2
if (foo()) { 
    // what to do if false 
} else { 
    // what to do if true 
} 

このアプローチの問題は過剰ネスティングです。 、過剰ネスティング問題を解決するため、戻り値を反転させるには

if(foo1()) { 
    if(foo2()) { 
     if(foo3()) { 
      // the rest of your code 
     } else { 
      // handle error 
     } 
    } else { 
     // handle error 
    } 
} else { 
    // handle error 
} 

if(!foo1()) { 
    // handle error 
    return; 
} 

if(!foo2()) { 
    // handle error 
    return; 
} 

if(!foo3()) { 
    // handle error 
    return; 
} 

このソリューションは、別の問題に苦しんでいるあなたは、あなたが呼び出したい3つの機能を持っていると仮定します。プログラムロジックとエラー処理コードが混在しています。これはすべてを複雑にします。理想的には、プログラムロジックとエラー処理を分離したいとします。この問題はGotoで修正できます

if(!foo1()) 
    goto error1; 

if(!foo2()) 
    goto error2; 

if(!foo3()) 
    goto error3; 

return; 

error1: 
    // handle error 
    return; 
error2: 
    // handle error 
    return; 
error3: 
    // handle error 
    return; 

多くのクリーナー。

また、gotoはリソースの割り当て解除の問題を解決できます。詳細については、Eli BenderskyのUsing goto for error handling in Cを参照してください。

+0

待機していますが、「非」何かがゼロでないと必ずしもゼロになるわけではありませんか? –

+0

"オペランドが0の場合は結果は1、オペランドが0でない場合は0になります。 http://c.comsci.us/etymology/operator/logicalnot.html – Jay

+0

はい、しかし、Cではファーストクラスのブール型がないので、!整数オペランドの算術否定だけですか?それは論理的な否定ではありません、そうですか?それはちょうどビットを反転させます。 –

関連する問題