2010-09-13 19 views
10

Nello sviluppo di un ampio progetto di programmazione C++ con molti sviluppatori, abbiamo riscontrato problemi con l'uso inappropriato di assert() nel codice che risulta in una qualità scadente in cui l'affermazione si verifica effettivamente e il prodotto si blocca.Quando deve essere usato assert()?

La domanda è quali sono i buoni principi da applicare per utilizzare assert() in modo appropriato? Quando è appropriato usare un assert() e quando no? Esiste un elenco di criteri che ogni asserzione deve superare per essere legittimi? Come possiamo incoraggiare un uso corretto di assert()?

Come primo tentativo, direi che assert() deve essere utilizzato solo per documentare una condizione che è ritenuta impossibile da raggiungere e che dovrebbe essere identificata come un assert() fallimento in fase di esecuzione dove mai sorgere perché le ipotesi di programmazione vengono violate.

La gente può fare meglio di così? Qual è la tua esperienza con assert()?

+3

Utilizzare affermare quando si sa che alcune condizioni devono prevalere affinché il codice sia considerato "buono". Se l'assert fallisce, per definizione il codice deve essere corretto. –

+1

@Robert: concordato +1, ma è necessario prendere in considerazione la quantità di lavoro che l'utente perderà se l'attivazione di asserzione interrompe il programma. È fastidioso quando un browser perde un insieme di schede aperte, ma di solito non è un disastro; è un disastro se un word processor perde un giorno di lavoro a causa di un'affermazione. Le parti difficili sono (a) capire se è sicuro fare qualsiasi cosa e (b) mantenere il sistema in uno stato in cui può essere recuperato se qualcosa va storto. –

+0

Chi vive un'intera giornata senza salvare il proprio lavoro ottiene ciò che merita quando si verifica un'affermazione. –

risposta

10

Uso eccezioni per condizione di errore che provengono dal esterno (fuori del metodo o all'esterno del programma) come controllo parametro e mancanti/difettosi le risorse esterne come file o connessioni o input dell'utente.

Uso asserzioni per indicare un interne difetti quali errori di programmazione, condizioni che non dovrebbero verificarsi, ad esempio invarianti di classe/metodo e stato del programma non valido.

2

Si dovrebbe usare assert per verificare tutte le condizioni che non dovrebbe mai accadere:

  • Presupposti su parametri di input
  • I risultati dei calcoli intermedi
  • Postcondizioni sullo stato oggetto

ma si dovrebbe includere quelli solo nelle build di debug o quando esplicitamente attivati ​​per il rilascio (non nelle build rilasciate ai clienti).

+1

Se le precondizioni errate ecc. Sono da codice * completamente * sotto il tuo controllo piuttosto che fallire, un'affermazione va bene. Ma che dire di situazioni come queste: dll mancanti/errate, voci di registro errate ecc. – seand

2

Io uso afferma per verificare qualsiasi stato programma indesiderato:

  • presupposti di funzione
  • A volte li inserisco in una macro dopo ogni chiamata API: glDrawArray(); checkOpenGLError(); --checkOpenGLError() chiamerà getGLError () se attivato
  • Integrità della struttura dei dati: assert (qualcosa == null);
  • A volte GDB mente per me (iOS SDK 3.2). Uso asserzioni per dimostrarlo.

EDIT:

"Stato programma indesiderato" esclude gli errori che si verificano naturalmente in fase di esecuzione, come l'essere in grado di aprire un file selezionato dall'utente a causa di autorizzazioni o fallimento HD. In questi casi non è saggio usare asserzioni.

0

Al giorno d'oggi gran parte del codice ha molte dipendenze e connessioni esterne.Non tendo ad usare le asserzioni tradizionali molto in questi giorni, privilegio le eccezioni. Non mi sembra di poter presumere che "questo non può mai accadere" e che i controlli possano essere rimossi in modo sicuro in una build non di debug.

Problemi correlati