2015-08-26 12 views
14

Ultimamente ho convertito alcune librerie per utilizzare le strutture <system_error> in C++ 11.Casi di utilizzo per std :: error_code

Ho difficoltà a comprendere gli use case per std::error_code rispetto a std::error_condition.

Nota, Capisco la differenza - ci sono many questions on stackoverflow che vanno oltre la differenza.

La differenza di base è che std::error_code rappresenta un errore specifico di sistema o piattaforma, mentre std::error_condition è un errore astratto che deve restituire un'interfaccia API o utente.

Ok, ma ho difficoltà a capire perché dovremmo usare mai lo std::error_code nella pratica. Mi sembra che stai o sta per:

  1. avere a che fare con un meccanismo specifico sistema di segnalazione degli errori (come dicono, errno o qualcosa restituito da una chiamata POSIX, o dire, una chiamata a getsockopt con SO_ERROR su Linux) che puoi facilmente convertire in un std::error_condition tramite le enumerazioni std::errc, che dovrebbero essere portatili.

  2. utilizzeranno una categoria definita dall'utente degli errori, che rappresentano a livello di applicazione o di business-logic errori, come "numero di previdenza sociale valido" o qualunque - che pure sarebbe un caso d'uso per std::error_condition.

  3. Si tratta di un'interfaccia di basso livello o di una libreria che definisce il proprio meccanismo di segnalazione degli errori, come OpenSSL, nel qual caso si utilizzeranno direttamente meccanismi di errore specifici della piattaforma. In questo caso dovresti quindi convertire o mappare questi errori in un std::error_code. Ma se hai intenzione di passare attraverso la difficoltà di convertire questi errori specifici della piattaforma in qualcosa di generico come std::error_code, perché non convertirlo in std::error_condition?

Inoltre, dal momento che gli errori di sistema POSIX dovrebbero essere portatile, e dal momento che mappa uno-a-uno con std::error_condition tramite il std::errc enum, non riesco a trovare alcun caso d'uso per std::error_code. La maggior parte delle chiamate di sistema Linux/UNIX è impostata su errno, che dovrebbe essere mappato in modo da portarlo su std::error_condition.

Quindi, non vedo alcun caso di utilizzo per std::error_code ovunque. Quindi, quali sono alcuni esempi di casi d'uso in cui vorremmo utilizzare std::error_code anziché std::error_condition?

+0

Che dire [questo] (http://stackoverflow.com/a/16687434/560648) non è chiaro? –

+0

@LightnessRacesinOrbit, l'idea è chiara, ma in pratica non vedo l'uso di 'error_code'. Il link che hai fornito dice: "Ogni oggetto' std :: error_code' contiene una coppia di codice di errore proveniente dal sistema operativo, o qualche interfaccia di basso livello "- okay, ma il sistema operativo ti darà un errore POSIX (che è portatile e può essere facilmente convertito in 'std :: error_condition') o qualche altro tipo di errore di basso livello (come ad esempio un errore Win32, per esempio), che dovresti quindi mappare manualmente a' std :: error_code' - ma a che serve mapparlo a error_code? ... – Siler

+0

... se devi fare qualcosa di specifico della piattaforma, lavori direttamente con le strutture della piattaforma. Se hai bisogno di convertire l'errore in qualcosa di più generico, usi error_condition. Non vedo come error_code si adatta a tutto ciò. – Siler

risposta

13

Me ne stavo chiedendo da tempo e ho trovato la risposta here. In sostanza, error_code viene utilizzato per memorizzare e trasportare i codici di errore, mentre error_condition viene utilizzato per abbinare i codici di errore.

void handle_error(error_code code) { 
    if  (code == error_condition1) do_something(); 
    else if(code == error_condition2) do_something_else(); 
    else        do_yet_another_thing(); 
} 

Ogni error_condition equivale ad un insieme di error_code, possibilmente da diversi error_categories. In questo modo puoi trattare tutti gli errori di un certo tipo uguali, indipendentemente dal sottosistema da cui provengono.

error_code d'altra parte contiene esattamente la categoria del sottosistema da cui ha avuto origine. Questo è utile per il debug e quando si segnala l'errore: potrebbe essere interessante sapere se un errore di "autorizzazione negata" era dovuto a diritti di accesso insufficienti sul file system locale oa causa di un errore 403 ricevuto dalla propria libreria di downloader http, e potrebbe voler mettere quel dettaglio nel messaggio di errore, ma il tuo programma deve interrompere in entrambi i modi.

Ciò che costituisce l'equivalenza è definito dalle categorie; se il error_code 's categoria considera il error_condition equivalente, o il error_condition' s categoria considera il error_code equivalente, poi operator== rendimenti true per quel paio di error_condition e error_code. In questo modo puoi avere error_code s dalla tua stessa categoria di errore e renderli equivalenti ad alcuni generici o di sistema error_condition s.

+2

Vorrei chiarire che una libreria dovrebbe segnalare errori con 'error_code's e dichiarare o riutilizzare le enumerazioni standard' error_condition' per farle corrispondere. In questo modo vengono fornite informazioni complete su un errore e un utente di tale libreria può stamparlo nel registro o così. Ma i dettagli aggiuntivi sono nascosti dalla logica superiore del programma. –

+0

Accetto con spiegazione. Ciò suggerisce anche che le API dovrebbero preferire propagare 'error_code' come valore di errore effettivo non-lossy, dove i risultati del test del codice di un'operazione dovrebbero causare la conversione implicita a' error_condition' dove potrebbero essere definite altre categorie per il sistema di compressione e compressione- specifici valori di errore in scenari di errore indipendenti dalla piattaforma. – charley

0

this blog copre quello che ti serve

e si può anche leggere questo "Your own error code"

+0

Le risposte di solo collegamento non sono appropriate per SO - invece la risposta dovrebbe rispondere alla domanda e puoi fornire un link per supportare riferimenti o ulteriori letture. Proprio quello che la risposta esistente fa in effetti. –