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 asserte abortsia 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
#defines 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
NDEBUGquesto 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.