2012-09-24 29 views
9

リリースビルドでQ_ASSERTのセマンティクスについて明確なステートメントを見つけることができません。アサーションチェックがない場合、アサートされた式はまったく評価されますか?Q_ASSERTリリースビルドのセマンティクス

は、すべての潜在的なQtの下

Q_ASSERT(do_something_report_false_if_failed()); 

ウィルdo_something_report_false_if_failed()ラン構成を構築し、次のコードを考えてみましょうか? (もう少し冗長で読みにくくもかかわらず)の代わりにこれを行うには、それはより安全になります:

bool is_ok = do_something_report_false_if_failed(); 
Q_ASSERT(is_ok) 

後者のアプローチは失敗が少ない冗長でアサート欠点を持っていますが、おそらくそれは、より明確に文があることを示しています実行された?

答えて

15

Q_ASSERTの中の式は、ではありません。は、非デバッグビルド構成で評価されます。

以下のソースコードをQt repoから考えてみましょう。

#if !defined(Q_ASSERT) 
# ifndef QT_NO_DEBUG 
# define Q_ASSERT(cond) ((!(cond)) ? qt_assert(#cond,__FILE__,__LINE__) : qt_noop()) 
# else 
# define Q_ASSERT(cond) qt_noop()  
# endif  
#endif 

QT_NO_DEBUGが定義されている場合、全体Q_ASSERT文がそれによって以前に含まれていること任意の式を除去し、qt_noop()で置換されています。

Q_ASSERTステートメント内の式で作成された副作用には決して依存しないでください。技術的には、特定のビルド構成でQT_NO_DEBUGが定義されていないことを確認することは可能ですが、これはGood Idea™ではありません。

+0

これは、通常の 'assert'と' NDEBUG'マクロと全く同じ状況です。 –

14

これはQt5.5に異なるように思える(しかし、それ以前ではない - Qt5.4を参照してください):

私は今の多く取得してい
#if !defined(Q_ASSERT) 
# if defined(QT_NO_DEBUG) && !defined(QT_FORCE_ASSERTS) 
# define Q_ASSERT(cond) do { } while ((false) && (cond)) 
# else 
# define Q_ASSERT(cond) ((!(cond)) ? qt_assert(#cond,__FILE__,__LINE__) : qt_noop()) 
# endif 
#endif 

:Visual Studioで「警告C4127は、条件式が一定である」2013年

更新: Qt5.5 release notesは言う:

Q_ASSERTは今場合でも、リリースモードで状態を拡大していきます アサートは、到達不能なコードパスではあるが、無効になっています。この は、アサーションでのみ使用されたため、リリースモードで未使用の変数と関数についてのコンパイラの警告を解決します。 残念ながら、#ifndef経由でこれらの関数と変数 を隠したコードベースでは、Qt 5.5でコンパイルするために条件文を削除する必要があります。

+0

Q_ASSERTとQ_ASSERT_Xをnoopに再定義すると便利です – user2846246

+2

これはgerritの変更点です:https://codereview.qt-project.org/#/c/94460/3 – Uflex

+0

私は同じ問題を抱えています。 Qtバージョン5.5以上で修正されましたか? – Knitschi

関連する問題