I can't find a clear statement on the semantics of Q_ASSERT under release builds. If there is no assertion checking, then is the asserted expression evaluated at all?
Consider the following code
Q_ASSERT(do_something_report_false_if_failed());
Will do_something_report_false_if_failed()
run under all potential Qt build configurations? Would it be safer (even though a bit more verbose and less readable) to do this instead:
bool is_ok = do_something_report_false_if_failed();
Q_ASSERT(is_ok)
The latter approach has the downside that ASSERT failures are less verbose, but perhaps it shows more clearly that the statement is executed?
The expression inside the Q_ASSERT
will not be evaluated in non-debug build configurations.
Consider the source code below from the 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
If QT_NO_DEBUG
is defined, then the entire Q_ASSERT
statement is replaced with a qt_noop()
, thereby removing any expression that it previously contained.
Never rely on any side effects created by an expression inside a Q_ASSERT
statement. Technically it is still possible to ensure that QT_NO_DEBUG
is not defined in a specific build configuration, but this is not a Good Idea™.
This seems to be different in Qt5.5 (but not earlier - see 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
I'm now getting lots of "warning C4127: conditional expression is constant" in Visual Studio 2013.
Update: Qt5.5 release notes say:
Q_ASSERT will now expand the condition even in release mode when asserts are disabled, albeit in an unreachable code path. This solves compiler warnings about variables and functions that were unused in release mode because they were only used in assertions. Unfortunately, codebases that hid those functions and variables via #ifndef will need to remove the conditionals to compile with Qt 5.5.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With