2012-09-24 10 views
9

No puedo encontrar una declaración clara sobre la semántica de Q_ASSERT en versiones de lanzamiento. Si no hay verificación de aserción, ¿se evalúa la expresión afirmada?Semántica de compilación de la versión de Q_ASSERT

considere el siguiente código

Q_ASSERT(do_something_report_false_if_failed()); 

Will do_something_report_false_if_failed() funcionamiento bajo todas las configuraciones posibles Qt construir? ¿Sería más seguro (aunque un poco más detallado y menos legible) de hacer esto en su lugar:

bool is_ok = do_something_report_false_if_failed(); 
Q_ASSERT(is_ok) 

Este último método tiene la desventaja de que aseveran omisiones son menos detallado, pero tal vez se nota más claramente que la declaración es ¿ejecutado?

Respuesta

15

La expresión dentro de Q_ASSERT será no evaluarse en configuraciones de compilación sin depuración.

Tenga en cuenta el código fuente siguiente a partir del 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 

Si se define QT_NO_DEBUG, entonces todo el Q_ASSERT declaración se sustituye con un qt_noop(), eliminando de este modo cualquier expresión que previamente contenía.

Nunca confíe en los efectos secundarios creados por una expresión dentro de una declaración Q_ASSERT. Técnicamente, aún es posible garantizar que QT_NO_DEBUG no esté definido en una configuración de compilación específica, pero esto no es una buena idea ™.

+0

Esa es exactamente la misma situación que con las macros 'assert' y' NDEBUG'. –

14

Esto parece ser diferente en Qt5.5 (pero no antes - ver 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 

Ahora estoy recibiendo un montón de "advertencia C4127: expresión condicional es constante" en Visual Studio 2013.

actualización: Qt5.5 release notes dicen:

Q_ASSERT ahora se ampliará el estado, incluso en modo de lanzamiento, cuando afirma que están deshabilitados, aunque en una ruta de código inalcanzable. Este resuelve las advertencias del compilador sobre las variables y funciones que fueron no utilizadas en el modo de lanzamiento porque solo se usaron en aserciones. Desafortunadamente, las bases de código que ocultaron esas funciones y variables a través de #ifndef necesitarán eliminar los condicionales para compilar con Qt 5.5.

+0

Redefinir Q_ASSERT y Q_ASSERT_X volver a noop ayuda a – user2846246

+2

Este es el cambio en gerrit: https://codereview.qt-project.org/#/c/94460/3 – Uflex

+0

Tengo el mismo problema. ¿Es esto fijo en las versiones de Qt> 5.5? – Knitschi

Cuestiones relacionadas