Tendo ad aggiungere molte asserzioni al mio codice C ++ per semplificare il debug senza influire sulle prestazioni delle build di rilascio. Ora, assert
è una macro C pura progettata senza i meccanismi C ++ in mente.
Il C ++ d'altra parte definisce std::logic_error
, che è pensato per essere lanciato nei casi in cui c'è un errore nella logica del programma (da cui il nome). Lanciare un'istanza potrebbe essere solo l'alternativa perfetta e più C ++ a assert
.
Il problema è che assert
e abort
sia terminare il programma immediatamente senza chiamare distruttori, quindi saltare la pulizia, mentre un'eccezione aggiunge manualmente i costi di esecuzione non necessari. Un modo per aggirare questo sarebbe creare una propria macro di asserzione SAFE_ASSERT
, che funziona proprio come la controparte C, ma genera un'eccezione in caso di errore.
Posso pensare a tre opinioni su questo problema:
- Attenersi all'asserzione di C. Poiché il programma viene terminato immediatamente, non importa se le modifiche vengono srotolate correttamente. Inoltre, usare
#define
s in C ++ è altrettanto dannoso. - Lancia un'eccezione e catturala in main () . Consentire al codice di saltare i distruttori in qualsiasi stato del programma è una cattiva pratica e deve essere evitato a tutti i costi, così come le chiamate a terminate (). Se vengono generate eccezioni, devono essere rilevate.
- Lancia un'eccezione e lascia che termini il programma. Un'eccezione che interrompe un programma va bene e, per
NDEBUG
questo motivo, ciò non accadrà mai in una build di rilascio. La cattura non è necessaria ed espone i dettagli di implementazione del codice interno amain()
.
C'è una risposta definitiva a questo problema? Qualche riferimento professionale?
Modificato: saltare i distruttori, ovviamente, non è un comportamento indefinito.
logic_error
è l'errore logico. Un errore nella logica del programma è chiamato bug. Non risolvi i bug generando eccezioni.