コンテキスト:gccの__builtin_unreachable()に解決されるマクロにassert()をラップしない理由はありますか?
if(condition) __builtin_unreachable();
完全に取り除かれ、condition
限り最適化のヒントとして使用されている:次のように見えるように、このanswerでは、私は、GCCの__builtin_unreachable()
は、いくつかの驚くほどインパクトのパフォーマンスへの影響を持つことができることを学びました副作用がないことを保証することができます。
だから、これまで私の即時の反応はassert()
内のコードを誘発する副作用は、最初の場所での主要なバグになるので、私は、次のマクロを作成し、私は通常assert()
を使用することになり、絶対にどこでもそれを使用するべきであるということです。
// TODO: add handling of other compilers as appropriate.
#if defined(__GNUC__) && defined(NDEBUG)
#define my_assert(condition) \
if(!(condition)) __builtin_unreachable()
#else
#define my_assert(condition) assert(condition)
#endif
基準の観点から、これはあなたが引数がassert()
の標準的な動作であることから、このマクロを除外させる可能性がある、通常とNDEBUG
ビルド間の機能での分割を作成します。しかし、私のコードは、アサーションの失敗の場合でも、機能的には死んでしまうので、行動的な見地から完全に同等です。
だから私の質問です:誰もこれをしない理由を考えてもらえますか(多くの迂回を含むアサルトから)
質問する前に、はい、gccの動作が無効になることを確認しました。アサーションをNDEBUG
ビルドにキャストします。
関連https://stackoverflow.com/a/40447259/817643 – StoryTeller
私が知る限り、これをしない理由はありません。リリースビルドでは最適化のためのものを想定し、デバッグビルドのアサーションで置き換えてプログラミングエラーをキャッチします。 – StoryTeller
デバッグアサーションには、しばしばデバッグモードでしか使用できない変数や呼び出しが含まれているため、「絶対にどこでも使用する」アプローチは実際には機能しません。より良いアイデアは、 'my_assume'のようなより適切な名前を持つ専用マクロを定義し、適切な場所でのみ使用することです。 – VTT