Я не могу найти четкое утверждение о семантике Q_ASSERT при сборке релиза. Если нет проверки утверждений, тогда оценивается ли утвержденное выражение вообще?
Рассмотрим следующий код
Q_ASSERT(do_something_report_false_if_failed());
Будет do_something_report_false_if_failed()
работать со всеми возможными конфигурациями сборки Qt? Было бы безопаснее (хотя и более многословно и менее читабельно) сделать это вместо этого:
bool is_ok = do_something_report_false_if_failed();
Q_ASSERT(is_ok)
У последнего подхода есть недостаток в том, что ошибки ASSERT менее многословны, но, возможно, он более четко показывает, что оператор выполняется?
Выражение внутри 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 ™.
Это, кажется, отличается в 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
Сейчас я получаю много «предупреждений C4127: условное выражение является константой» в Visual Studio 2013.
Обновить:
Замечания к выпуску Qt5.5 сказать:
Q_ASSERT теперь расширит условие даже в режиме освобождения, когда
утверждения отключены, хотя и в недоступном пути кода. это
решает предупреждения компилятора о переменных и функциях, которые были
не используется в режиме выпуска, потому что они использовались только в утверждениях.
К сожалению, кодовые базы, которые скрывали эти функции и переменные
через #ifndef нужно будет удалить условные выражения для компиляции с Qt 5.5.