2011-11-16 15 views
6

Spójrz na ten kod:Puste "wydanie" ASSERT makr awarie programu?

#include <cassert> 

#ifdef DEBUG 
#define ASSERT(expr) assert(expr) 
#else 
#define ASSERT(expr) 
#endif /* DEBUG */ 

Program będzie działał tylko wtedy, gdy mam DEBUG zdefiniowane, inaczej będzie powiesić i zakończyć bez rezultatów. Używam MinGW w Eclipse Indigo CDT. Rada jest doceniana!

Odpowiedz

7

Jesteś prawie na pewno nadużywania twierdzeń. Wyrażenie asercji nigdy nie może mieć efektów ubocznych.

Kiedy mówisz, assert(initialize_critical_space_technology());, a następnie pomijasz całą linię w kompilacji wydania, możesz sam sobie wyobrazić, co się stanie.

bezpieczny i zdrowy Jedynym sposobem, aby użyć twierdzenia jest na wartościach:

const bool space_init = initialize_critical_space_technology(); 
assert(space_init); 

Niektórzy ludzie wprowadzają VERIFY makro na coś, co zawsze wykonuje kod:

#define VERIFY(x) (x)   // release 
#define VERIFY(x) (assert(x)) // debug 
8

Trudno powiedzieć, nie patrząc na rzeczywisty kod powodujący problem. Zgaduję: oceniasz ekspresję z efektami ubocznymi w obrębie ASSERT(). Na przykład: ASSERT(++i < someotherthing) w pętli. Możesz potwierdzić, tymczasowo modyfikując definicję makra tylko na expr na kompilacjach NDEBUG. Po potwierdzeniu tego jest przyczyna, przejdź do każdego wywołania ASSERT, które wydajesz, aby upewnić się, że wyrażenia są wolne od skutków ubocznych.

+0

Prawdopodobnie jest to drugi najbardziej częstą przyczyną (po optymalizacji) różnic między kompilacjami debugowania i wydania. –

+0

Dzięki za odpowiedź, jedno pytanie. Czy dobrą praktyką byłoby po prostu '#define ASSERT (expr) (expr)' (jak wspomniała Kerrek SB) o braku debugowania i po prostu nie martwić się efektami ubocznymi od tego? Mam przeczucie, że mój kod będzie bardziej czytelny. – AutoBotAM

+0

@AutoBotAM: Jeśli zamiast tego nazwiesz 'ASSERT'' VERIFY', to na pewno. Ale nie zmieniaj definicji 'ASSERT', ludzie wiedzą i oczekują, że nie oceni ona wyrażenia na kompilacjach' NDEBUG'. –