Sto sviluppando un progetto di grandi dimensioni in C con altri membri del team e abbiamo un disaccordo su come lo stile di errori "questo non può mai accadere" dovrebbe essere gestito. Con questo intendo casi di errore che il codice attualmente non può mai raggiungere, ma qualcuno può modificare il codice e dopo la modifica è possibile che venga raggiunto il caso di errore.Come deve essere gestito lo stile di errori "questo mai accaduto" in C?
Ad esempio, supponiamo di avere una funzione che restituisce 0 in caso di successo o -EINVAL se ha un argomento NULL. Quello che faccio è naturalmente:
int err;
struct myctx ctx;
err = callFunction(&ctx);
if (err != 0)
{
abort();
}
o anche:
int err;
struct myctx ctx;
err = callFunction(&ctx);
if (err == -EINVAL)
{
abort();
}
else if (err != 0)
{
abort();
}
... a distinguere tra i due casi di -EINVAL e il codice di errore sconosciuto.
I vantaggi di questo approccio di gestione degli errori sono che è semplice programmare (poche righe di codice) e lascia un file principale che può essere utilizzato per eseguire rapidamente il debug della situazione.
Tuttavia, alcuni membri del team non sono d'accordo con questo approccio di gestione degli errori perché sto facendo un'uscita non pulita e mentre il codice attualmente non può mai raggiungere la riga abort() è possibile che in futuro qualcuno modifichi il codice e raggiunga la linea abort() quindi. Secondo loro, dovrei provare a fare un'uscita controllata e stampare il motivo per l'utente. Quindi, credo che invece di questo devo fare:
int err;
struct myctx ctx;
err = callFunction(&ctx);
if (err == -EINVAL)
{
fprintf(stderr, "Argument was NULL in file %s line %d\n", __FILE__, __LINE__);
exit(1);
}
else if (err != 0)
{
fprintf(stderr, "Error was %d in file %s line %d\n", err, __FILE__, __LINE__);
exit(1);
}
A mio parere, questa seconda strategia di gestione degli errori è peggio, perché non lascia alle spalle un componente del sistema che può essere utilizzato per eseguire il debug di questa situazione. Inoltre, risulta in codice che ha più linee di codice.
Quindi, la domanda è: come deve essere gestito lo stile di errori "questo non può mai accadere in C"? Devo fare una interruzione o un'uscita controllata con un messaggio di errore descrittivo?
Mentre mi piace la domanda, sembra essere piuttosto basata. – martin
Quest'ultimo è migliore - non si ottiene un core dump ma si ottiene una traccia che dice esattamente dove si è verificato il problema, e l'utente ottiene un'esperienza (leggermente) migliore (è possibile migliorare il messaggio di errore, ma un core dump non appare mai Potresti scrivere il core dump anche usando abort invece di exit, il che sarebbe meglio a tutto tondo, oppure potresti utilizzare la lib di coredumper di google per scrivere il dump e poi uscire (anche se, perché non interrompere in questo caso - dead è morto se si esce o si interrompe) – gbjbaanb
Grazie! Non sapevo che esiste una libreria di coredumper che consente di generare un core dump da un'applicazione in esecuzione. Ero consapevole del gcore, però, ma è un comando separato e non una libreria che l'applicazione potrebbe utilizzare per generare un coredump di se stesso – juhist