Utilizzo delle asserzioni rispetto alle eccezioni di lancio?

31

Spesso quando scrivo una funzione voglio assicurarmi che gli input siano validi al fine di rilevare tali errori il prima possibile (credo che questi siano chiamati precondizioni). Quando una precondizione fallisce, ho sempre lanciato un'eccezione. Ma sto cominciando a dubitare che questa sia la migliore pratica e se non le affermazioni sarebbero più appropriate.

Quindi quando dovrei fare quale: quando è opportuno usare un'asserzione e quando è opportuno lanciare un'eccezione?

    
posta gablin 29.10.2010 - 11:01
fonte

4 risposte

43

Le asserzioni dovrebbero essere usate solo per verificare che le condizioni logicamente impossibile siano false (leggi: controlli di integrità). Queste condizioni dovrebbero essere basate solo su input generati dal tuo codice. Qualsiasi controllo basato su input esterni dovrebbe utilizzare eccezioni.

Una semplice regola che tendo a seguire è la verifica degli argomenti delle funzioni private con gli asserzioni e l'utilizzo di eccezioni per gli argomenti delle funzioni pubbliche / protette.

    
risposta data 29.10.2010 - 11:18
fonte
24

Le asserzioni sono usate per trovare errori di programmazione. I tuoi programmi devono funzionare altrettanto bene quando tutte le asserzioni vengono rimosse.

Le eccezioni, d'altra parte, sono per situazioni che possono accadere anche quando il programma è perfetto; sono causati da influenze esterne, come hardware, rete, utenti ecc.

    
risposta data 29.10.2010 - 11:04
fonte
2

La tipica pratica di programmazione consiste nel compilare asserzioni da build di produzione / rilascio. Le asserzioni aiuteranno solo durante i test interni per rilevare il fallimento delle ipotesi. Non dovresti assumere il comportamento di agenzie esterne, quindi non dovresti far valere gli eventi della rete o dell'utente. Inoltre è una buona pratica scrivere codice di gestione per le build di produzione nel caso in cui un'asserzione fallisca.

Ad esempio in C,

int printf(const char *fmt, ...)
{
  assert(fmt);  // may fail in debug build but not in production build
  if (!fmt) return -1; // handle gracefully in production build
  ...
}

Le eccezioni sono pensate per essere incorporate nelle build di produzione. L'alternativa per eccezione restituisce errori e non asserzioni.

    
risposta data 29.10.2010 - 12:06
fonte
0

Un problema con le affermazioni per me è che sono disabilitate di default in Java.

Utilizziamo una strategia fail-first in cui il programma, che potrebbe essere stato eseguito in modo incustodito per anni, deve arrestarsi il prima possibile per evitare il danneggiamento dei dati in caso di dati non validi (in forma non prevista). Questo è ciò che usiamo per il controllo e, usando le asserzioni, fondamentalmente rischiamo di non essere attivi.

    
risposta data 29.10.2010 - 12:03
fonte

Leggi altre domande sui tag