2012-09-24 15 views
9

Nie mogę znaleźć jasnego oświadczenia na temat semantyki Q_ASSERT pod kompilacjami wydań. Jeśli nie ma sprawdzania asercji, to czy to wyrażenie jest w ogóle ocenione?Q_ASSERT release build semantics

Rozważmy następujący kod

Q_ASSERT(do_something_report_false_if_failed()); 

Will do_something_report_false_if_failed() działać pod wszystkimi potencjalnymi Qt budować konfiguracje? Byłoby bezpieczniejsze (choć nieco bardziej rozwlekły i mniej czytelny), aby to zrobić w zamian:

bool is_ok = do_something_report_false_if_failed(); 
Q_ASSERT(is_ok) 

To ostatnie rozwiązanie ma tę wadę, że twierdzą, awarie są mniej gadatliwy, ale chyba to widać wyraźniej, że oświadczenie jest wykonany?

Odpowiedz

15

Wyrażenie wewnątrz wartości Q_ASSERT będzie oceniane w kompilacjach bez debugowania.

Należy wziąć pod uwagę kod źródłowy poniżej z 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 

Jeśli QT_NO_DEBUG jest określona, ​​wówczas cała Q_ASSERT stwierdzenie jest zastąpiony qt_noop(), usuwając w ten sposób zawierać dowolną poprzednio ograniczona.

Nigdy nie należy polegać na żadnych efektach ubocznych utworzonych przez wyrażenie wewnątrz instrukcji Q_ASSERT. Technicznie nadal można zagwarantować, że QT_NO_DEBUG nie jest zdefiniowany w konkretnej konfiguracji kompilacji, ale nie jest to Good Idea ™.

+0

Dokładnie taka sama sytuacja jak w przypadku zwykłych makr "assert' i' NDEBUG'. –

14

To wydaje się być różny w Qt5.5 (ale nie wcześniej - patrz 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 

Jestem teraz coraz dużo "Ostrzeżenie C4127: wyrażenie warunkowe jest stała" w Visual Studio 2013.

Aktualizacja: Qt5.5 release notes powiedzieć:

Q_ASSERT będzie teraz poszerzyć stan nawet w trybie uwalnianiu Potwierdzenia są wyłączone, aczkolwiek w nieosiągalnej ścieżce kodu. Ten numer rozwiązuje ostrzeżenia kompilatora dotyczące zmiennych i funkcji, które były nieużywane w trybie zwolnienia, ponieważ były używane tylko w asercji. Niestety, bazy kodowe, które ukryły te funkcje i zmienne przez #ifndef będą musiały usunąć warunkowe kompilacje z Qt 5.5.

+0

Przedefiniowanie Q_ASSERT i Q_ASSERT_X z powrotem na noop pomaga – user2846246

+2

To jest zmiana w gerrit: https://codereview.qt-project.org/#/c/94460/3 – Uflex

+0

Mam ten sam problem. Czy to naprawiono w wersjach Qt> 5.5? – Knitschi

Powiązane problemy