2012-05-14 12 views
11

Ich schreibe eine C-Bibliothek für ein Softwareprojekt. Ich muss einige Fehler melden, aber ich bin ein bisschen zu faul, um meine eigenen komplexen Fehlercodes, Variablen und Funktionen zu implementieren. Ist es akzeptabel, die von libc zur Verfügung gestellte errrno-Funktion für benutzerdefinierte Fehlerberichte zu verwenden? Alle meine Fehler passen in die Kategorien E... Makros.Verwenden von Fehlernummern für Anwendungs-/Bibliotheksfehlerberichte

Nehmen wir zum Beispiel an, dass mein Code eine Funktion enthält, die einen SHA256-Hash in hexadezimaler Schreibweise liest und ihn in eine Art internes Format konvertiert. Ich mag errno verwenden, um Fehler zu melden:

#include <errno.h> 

int hash_fromstr(hash_t *out, const char *in) { 
    /* ... */ 

    if (strlen(in) != 65) { 
    errno = EINVAL; 
    return -1; 
    } 

    /* ... */ 
} 

Natürlich ist dieses Beispiel lächerlich vereinfacht wird, in Wirklichkeit viel mehr Fehler in anderen Funktionen passieren können.

+0

Solange Ihre Bibliothek die Standardfehlercodes ausgeben kann, ohne die ordnungsgemäße Funktion von 'errno' in anderen Teilen einer Benutzeranwendung, die mit Ihrer Bibliothek verknüpft ist, zu unterbrechen, sehe ich kein Problem damit. Vielleicht könnten Sie die Variable 'errno' verwenden, aber nicht ändern und eine Kopie davon zurückgeben? – Chimera

+0

@Jim Ich möchte 'errno' für Fehler verwenden, die innerhalb der Bibliothek selbst auftreten - nicht notwendigerweise in der Funktion der libc, die von der Bibliothek aufgerufen wird. – fuz

+1

Also fragen Sie, ob es in Ordnung ist, den Wert von 'errno' zu setzen, um Fehler beim Aufrufer Ihrer Bibliothek zu melden? Wenn ja, möchtest du vielleicht http://stackoverflow.com/questions/9856822/should-i-set-errno – Chimera

Antwort

2

Viele Menschen würden dies geschmacklos halten. Zuallererst besteht das Muster darin, eine eigene Variable mit einer Reihe spezifischer Werte zu erstellen, die auf Ihr Problem abgestimmt sind. Zweitens gibt es die Frage der Thread-Sicherheit, die für Errno durch Tricks behandelt wird.

Sind Sie sicher, dass Sie keine zusätzliche int* zu jeder Funktion hinzufügen möchten, um einen Statuswert zu erhalten?

+11

Die letzte Option, die Sie sagen, ist extrem hässlich und laut. Ich möchte nicht, dass Benutzer der Bibliothek jeder Funktion ein zusätzliches Argument hinzufügen. IMHO Fehlerbehandlung sollte so unsichtbar wie möglich, aber leistungsstark sein. – fuz

+0

Dann sollten Sie eine weniger primitive Programmiersprache als C. in Betracht ziehen. – bmargulies

+1

@bmargulies: Wenn es wie ich ist, werden Sprachen von einem höheren Managementteam ausgewählt, nicht von den einzelnen Mitwirkenden. – dreamlax

4

Sie können den Wert von errno ändern, wie Sie möchten, stellen Sie sicher, dass Ihr Bibliothekscode prüft, dass errno nicht eingestellt ist, bevor Sie sicherstellen, dass Ihr Bibliothekscode interne Fehler intern korrekt erkennt, die zu Fehlern führen . Weitere Informationen finden Sie unter "should I set errno".

0

Ja, Sie können es ändern und es hat Thread-Bereich, der in dieser Art der Fehlerbehandlung sehr wünschenswert ist.

Mit errno Fehler Familie (E...) und vielleicht erweitern es kann eine sehr leistungsfähige, aber einfache Fehlerbehandlung Muster sein. Es kann als schlecht geschmeckt Ansatz von anderen betrachtet werden, aber IMHO produziert es sauberer Code und ein standardisiertes Muster für die Fehlerbehandlung.

+0

Wie können Sie 'errno' erweitern? Soweit ich weiß, gibt es keinen portablen Weg, um herauszufinden, welche 'errno'-Werte nicht zugewiesen sind und selbst wenn Sie dies tun, bekommen Sie einen Konflikt mit anderen Bibliotheken, die versuchen, dasselbe zu tun. – fuz

+0

@FUZxxl Es ist wahr, dass es nicht möglich ist zu wissen, welche Werte nicht zugeordnet sind, aber der Typbereich int ist groß genug, um eine sichere Marge zu berücksichtigen. Über die Konflikte sehe ich keine Konflikte, wenn man bedenkt, dass der errno-Wert nur den Umfang eines einzelnen Funktionsaufrufs hat, so dass der Fehler abhängig von der Bibliothek nur gegen die Bibliotheksfehlerliste verarbeitet werden sollte, um Konflikte zu vermeiden. Sind Sie einverstanden? –

+0

@fani Ich stimme nicht zu, da die Verwendung von 'errno' für benutzerdefinierte Dinge Dinge wie' strerror' unterbricht - der benutzerdefinierte 'errno'-Wert bleibt nach einem fehlgeschlagenen Bibliotheksaufruf erhalten und führt möglicherweise zu einer Störung außerhalb der Verarbeitung. – fuz