2012-10-04 13 views
8

ho il mio tipo di ritorno e funzioni definite in questo modo:Regola generale: valori negativi o positivi per il codice di errore in C/C++

typedef enum xx_return_t { 
    success = 0, 
    general_error = -1, 
    specific_error = -2, 
    [...] 
} xx_return_type; 

xx_return_type generalFunction(void) { 
    if(there_was_an_error) 
     return general_error; 
} 

Tuttavia io sono un po 'incerto sui valori di tipo errore qui; qual è lo standard/procedura consigliata per i valori dei ritorni di errore in C/C++ - negativo o positivo?

Aggiornamento: Grazie per le vostre risposte! ero alla ricerca di informazioni sia su C e C++, ma mi rendo anche conto questo solleva buone domande sulla struttura e metodi generali (eccezioni, codici di errore, restituisce oggetti, ecc) specifici di ogni lingua.

+0

Stai chiedendo di C o C++? – Default

risposta

15

Si tratta di due domande completamente diverse (versioni C e C++) mascherate da una sola.

In C++ la risposta è semplice: utilizzare i valori restituiti per i valori restituiti e utilizzare eccezioni per i casi di errore/eccezione. Non utilizzare i valori restituiti per il controllo degli errori in C++ puro (una libreria API C in C++ è una storia diversa).

In C non si dispone di tale opzione, quindi suggerirei di utilizzare 0 per i numeri di successo e negativi per i codici di errore. Ciò lascia la flessibilità, se lo si desidera, di utilizzare numeri positivi per ulteriori informazioni di successo (ad esempio chiamate read)

+1

Il migliore finora! {filler} –

+2

Per quanto riguarda le eccezioni in C++, vorrei sottolineare che non significa che improvvisamente tutti i metodi dovrebbero "lanciare". Ad esempio: 'T const * MyMap :: find (std :: string const & name);' è un metodo che non deve essere lanciato quando il nome non è stato trovato; può solo restituire un puntatore nullo. –

+0

Sono d'accordo con Matthieu. Le eccezioni dovrebbero essere lanciate solo in caso di eventi eccezionali, non risultati ordinari negativi di una ricerca, ecc.L'eccezione di lancio è molto più lenta del fatto che restituisce il valore dalla funzione e anche se non viene lanciato il blocco try {} catch() stesso e l'inclusione di tutte le macchine di gestione delle eccezioni rallenta il programma. – 4pie0

1

Meglio usare 0 (zero) e non zero in modo che possano essere considerati booleani. Tipicamente false è 0, e true è qualsiasi altra cosa.

+0

Questo è quello che sta facendo e diverso da zero può essere negativo e positivo ... –

+1

@LuchianGrigore In realtà, sta facendo il contrario. Come hai detto, entrambi sono comuni, ma è bello poter usare anche true/false. – Brady

+0

Come si chiama il contrario? "usando 0 e non zero" in contrapposizione a "usando non zero e 0"? –

4

C++:

  1. E 'una questione di scelta, ho visto entrambe le cose.
  2. utilizzare le eccezioni!
+4

"2." funziona particolarmente bene per questo tag 'c' ;-) –

+4

(Vorrei che ci fosse l'opzione' + 0.5' ;-)) –

+3

@ MichaelKrelin-hacker: È sempre un problema con le domande C/C++. O è C o è C++ ... –

2

Non so su C ...

... ma in C++ l'idea non è quella di utilizzare i codici di errore, in generale.

Non voglio dire che dovresti usare le eccezioni, ma un codice di errore non è davvero troppo informativo (manca il contesto, qual è il valore di FILE_NOT_FOUND quando il nome del file è sconosciuto?).

Nelle istanze in cui non ho usato eccezioni, tendevo a preferire oggetti di errore in piena regola. Un esempio potrebbe essere:

boost::variant<File, Error> open(std::string const& filename, FileMode mode); 

dove si otterrà un file o un errore, a seconda di quello che sta succedendo.

2

Ci sono diverse convenzioni tra cui scegliere:

  • Microsoft utilizza 0 = FALSE = errore per la maggior parte del suo alto livello di API di. e lasciare che l'utente cerchi l'errore specifico con una funzione globale GetLastError()
  • microsoft utilizza 0 = ok per apis di livello inferiore, come registro, audio o telefonia. Questi tutti restituiscono un tipo analogo a HRESULT, contenente il codice di errore specifico.
  • funzioni POSIX ritornano uno stato generalmente tornano -1 per errore, e consentono all'utente di ricercare gli errori tramite una variabile globale errno
  • funzioni che restituiscono un puntatore solito ritorno NULL per errore
  • funzioni C++ STL restituiscono 'end' per stato come 'non trovato'. errori come 'out-of-memory' sono segnalati usando un'eccezione.

In generale, è più importante utilizzare la convenzione in modo coerente, rispetto a quale convenzione si utilizza.

Btw, alcuni esempi di come non fare questo possono essere trovati nei file di intestazione di Microsoft:

#define S_OK  ((HRESULT)0x00000000L) 
#define S_FALSE ((HRESULT)0x00000001L) 

fate attenzione anche di due valori di errore diversi per HANDLE 's in Windows: 0 o INVALID_HANDLE_VALUE

Problemi correlati