2011-12-29 34 views
2

ASSERT(x)マクロがあり、それがアサートされている(リリース構成で)場合はreturnにコールしたいと思います。 これを行うには、私がこのASSERTを使用する関数の戻り値の型を知る必要があります。どうすればいいですか(私はC++03LLVM GCC 4.2コンパイラを扱います)?マクロで関数の戻り値の型を取得する(C++)

マイassertマクロ:

#define ASSERT(x) \ 
    if(!(x)) { 
     LOG ("ASSERT in %s: %d", __FILE__, __LINE__); \ 
     return /*return_type()*/; \ 
    } 

PS:私はreturn 0;を試してみました - コンパイラはvoid型関数のエラーを示して(と私は複雑な帰国のタイプのためにそれをしようとしなかった)、return;場合 - 非void型関数のエラーを。

(更新...)

私はここ werewindle、ナイアーラトテップJDV-ヤン・デ・ヴァンにお答えします。私はデバッグ設定のために標準assertを使用します。しかし、ベータテストの後、私はまだ、最終的な顧客からのクラッシュレポートを取得し、ほとんどの場合、私は私のクラッシュ機能を変更する必要があります。

ASSERT (_some_condition_); 
if (!_some_condition_)  // add this return 
    return _default_value_; 

私は私のプログラムが後でおそらくクラッシュすることがありますことを、理解し(それ以外の場合は間違いでクラッシュします現在の機能)。また、開発はiPhone向けであるため、アプリケーションを終了できません(アプリはプログラムで終了できない可能性があります)。したがって、アサーションが失敗した場合、最も簡単な方法は「自動復帰」です。

+0

、彼らはあなたが関係なく、あなたのプログラムが持っているもののバグ動作していない続けるだけ必要があることを意味するものではありません。彼らは**あなたのアプリはそれを提出する前にバグフリーでなければならないと言っています**! –

+0

iPhone - それはObjective-Cではなく、C++ではないですか? – codeling

+1

例外の使用について考えましたか?非常に高レベルのtry-catchブロックを持つことができ、例外オブジェクトに組み込むことができるメッセージ( '__FILE__'と' __LINE__'によって与えられた位置と共に)を記録することができるようです。あなたは戻り値に全く興味がないようですね、そうですか? – Andre

答えて

4

マクロ内の周囲の関数の戻り値の型は判別できません。マクロは、プリプロセッサによって展開されます。プリプロセッサは、これらのマクロが存在する環境に関するこの種の情報を持っていません。基本的にはマクロを検索して置き換えるだけです。戻り値の型ごとに別々のマクロを記述する必要があります。

しかし、なぜプログラムを終了しないでください(つまり、exit関数を呼び出します)?関数から戻るだけでは、非常に頑強なエラー処理のようには見えません。失敗したアサーションは何かがひどく間違っている(プログラムが処理するように設計されていない状態にあることを意味する)場合にのみ発生しますので、program as soon as possibleを終了することをお勧めします。

+0

コンパイラのベンダーが望んでいれば、もちろんそのようなマクロを追加することができます。 __LINE__、__FUNC__などと変わりはありません。 – lkanab

+0

何かを返す理由の1つは、すべての可能なフローを調べる静的解析ツールです。彼らが帰って来たら、彼らは流れが終わったことを知っている。彼らが出口に出会ったら - 彼らはしません。 – lkanab

0

マクロは、機能自体はありませんので、returnの値ではありません。マクロは、使用されているソースコードに置き換えられます。したがって、マクロが使用される関数内ではreturnになります。

return valueをマクロから取得する方法はありません。

2

C.

内の関数の内部で戻り値の型を決定するための適切な方法は、あなたが何らかの形でASSERTのバリアントを実装する場合、それは誤ったプログラムの振る舞いにつながる、また、ありません。 ASSERTの主なアイデア:それが失敗すると、プログラムは未定義の状態にあり、それを今すぐ中止するだけです。私。 exit()に電話してください。

1

あなたはそうすることはできません.C/C++プリプロセッサはかなり基本的であり、コード分析を行うことはできません。あなたができることは、戻り値の型をマクロに渡すことです。

しかし、ここに私の意見です:間違った方法でアサーションを使用しています。コードの健全性チェックにのみ使用するべきです(プログラマーのために発生するエラーよりも)。アサーションがすべて合格した場合は、アサーションを気にする必要はありません。ログを記録する必要はありません。

それだけでなく、(一般的に)少なくとも驚きの要素を使用する必要があります。 ASSERTに何かを記録させて、強制的に関数を復帰させることを期待していますか?私はそうではないことを知っている。私はそれがアプリケーションを完全に(標準assertが何をしているか)終了するか、次に何が起こるかを決めることを期待しています(おそらく私はいくつかの無料のポインタを持っています)。

0

私はあなたがマクロ内からデフォルト(x)を呼び出すテンプレート関数でこれを行うことができると思います。

template<class T> default<T>(T x) { return T(); } 

デフォルトのコンストラクタを使用しています。私はvoidのための特別なマクロを書く必要があると思います。

私はテンプレートの構文が正しいと思っています。私のC++は錆びています。

+0

'default()'に渡す引数は何ですか? – brigadir

+0

戻り値。これは、パラメータのないctorから出てくるタイプTのデフォルト値を返します。 –

0

必要に応じて別のマクロを定義できます。

#define ASSERT(x) \ 
    if(!(x)) { \ 
     LOG ("ASSERT in %s: %d", __FILE__, __LINE__); \ 
     ASSERT_DEFAULT_RETURN(); \ 
    } 

そして、関数内

:彼らはアプリだけで、プログラム終了することはできませんことを言うとき

int foo(){ 
#ifdef ASSERT_DEFAULT_RETURN 
#undef ASSERT_DEFAULT_RETURN 
#endif 
#define ASSERT_DEFAULT_RETURN() return 0 
    // ... 
    ASSERT(some_expression); 
    // ... 
    // cleanup 
#undef ASSERT_DEFAULT_RETURN 
} 
+0

これは十分に繊細ではありませんが、解決策である可能性があります。最小限のコーディングで 'ASSERT(condition、return_command)'のようになり、 'ASSERT(x、return 0);' – brigadir