2012-09-24 12 views
9

Non riesco a trovare una dichiarazione chiara sulla semantica di Q_ASSERT in build di rilascio. Se non c'è un controllo di asserzione, allora l'espressione asserita è valutata?Q_ASSERT release semantics build

Si consideri il seguente codice

Q_ASSERT(do_something_report_false_if_failed()); 

Will do_something_report_false_if_failed() corsa in tutte le possibili configurazioni di Qt costruire? Sarebbe più sicuro (anche se un po 'più prolisso e meno leggibile) per fare questo, invece:

bool is_ok = do_something_report_false_if_failed(); 
Q_ASSERT(is_ok) 

Quest'ultimo approccio ha il rovescio della medaglia che affermano fallimenti sono meno prolissa, ma forse si vede più chiaramente che la dichiarazione è eseguito?

risposta

15

L'espressione all'interno dello Q_ASSERT sarà non essere valutata in configurazioni di build non di debug.

Considerare il codice sorgente riportato di seguito dal 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 

Se QT_NO_DEBUG è definito, allora l'intero Q_ASSERT dichiarazione è sostituito con un qt_noop(), eliminando qualsiasi espressione che conteneva precedentemente.

Mai fare affidamento su alcun effetto collaterale creato da un'espressione all'interno di una dichiarazione Q_ASSERT. Tecnicamente è ancora possibile garantire che QT_NO_DEBUG non sia definito in una configurazione di build specifica, ma questa non è una buona idea ™.

+0

Questa è esattamente la stessa situazione con la normale macro 'assert' e' NDEBUG'. –

14

questo sembra essere diversa in Qt5.5 (ma non prima - vedi 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 

ora sto ricevendo un sacco di "avviso C4127: espressione condizionale è costante" in Visual Studio 2013.

Aggiornamento: Qt5.5 release notes dicono:

Q_ASSERT ora ampliare la condizione, anche in modalità di rilascio, quando Gli invii sono disabilitati, anche se in un percorso di codice non raggiungibile. Questo risolve gli avvisi del compilatore su variabili e funzioni che erano non utilizzate in modalità di rilascio perché erano utilizzate solo nelle asserzioni. Sfortunatamente, le codebase che nascondevano quelle funzioni e variabili tramite #ifndef dovranno rimuovere i condizionali da compilare con Qt 5.5.

+0

Ridefinire Q_ASSERT e Q_ASSERT_X torna a noop aiuta – user2846246

+2

Questa è la modifica in gerrit: https://codereview.qt-project.org/#/c/94460/3 – Uflex

+0

Ho lo stesso problema. È stato risolto nelle versioni Qt> 5.5? – Knitschi

Problemi correlati