Warum eine negative Fehlernummer zurückgeben? (z. B. Rückgabe -EIO)

Lesezeit: 4 Minuten

Noch ein einfaches Beispiel:

if (wpa_s->mlme.ssid_len == 0)
    return -EINVAL;

Warum das unäre Minus? Wird dies (normalerweise) für Funktionen durchgeführt, die bei Erfolg > 0 und bei Fehlern < (=) 0 zurückgeben, oder gibt es einen anderen Grund?

  • Denn wir mögen nichts weniger als den ERFOLG!

    – Doug T.

    4. Dezember 2009 um 18:18 Uhr

  • Ich verstehe nicht, warum Leute ein Tag setzen “[C]” im Titel einer Frage. Jede Frage verknüpft immer, was ihre Tags sind (z. B. die Frage ist derzeit markiert [c], [errno], [return-value]. Warum haben Sie die Frage nicht mit “[C] [errno] [return-value] Warum eine negative Fehlernummer zurückgeben? (zB return -EIO)”???

    – Peter

    4. Dezember 2009 um 18:24 Uhr

  • Ich schaute auf den Titel der Frage und hatte sofort einen Anfall, gefolgt von tiefem Koma. Wenn ich nicht jederzeit ein schnelles Einsatzteam von Weltklasse-Hirnchirurgen in meinen Räumlichkeiten hätte, wer weiß, ob ich mich rechtzeitig erholt hätte, um die Frage zu beantworten?

    – Carl Smotricz

    4. Dezember 2009 um 18:27 Uhr

  • Ich habe die Sprache in den Titel geschrieben, weil es für die Leute, zumindest für mich, einfacher ist, sie zu erkennen, wenn sie die Liste der Fragen durchgehen, obwohl sie auch in der Liste der Tags enthalten ist.

    – Flucht

    4. Dezember 2009 um 18:31 Uhr

  • Tags reichen mir aus, SO kümmert sich darum, die Nachrichten mit Tags hervorzuheben, an denen ich interessiert bin.[C]” ist für mich nur laut (aber ich respektiere deinen Geschmack und werde den Titel nicht bearbeiten 🙂 )

    – Remo.D

    4. Dezember 2009 um 21:07 Uhr

Erstens ist das nicht wirklich ein C-Ding. Sie sehen sich eine Funktion an, die für einen bestimmten Zweck in C geschrieben wurde. Dieselben Konventionen könnten in jeder Sprache verwendet werden.

In meinen alten Unix-Tagen gab es so etwas wie eine Konvention, dass 0 Erfolg bedeutete, eine positive Zahl kleinere Probleme bedeutete und eine negative Zahl eine Art Misserfolg bedeutete. Daher gab es auch eine Art Konvention von if (foo() >= 0) { /* success of a sort */ }.

Dies hing zweifellos mit Rückgabecodes von Unix-Prozessen zusammen, bei denen 0 Erfolg bedeutete.

Das sind im Grunde die Gründe. Viele Funktionen haben viele “gute” positive Ergebnisse, so dass die negativen Werte für Fehlercodes übrig bleiben.

C / POSIX-Fehlercodes sind ein bisschen “historisch gewachsen”, daher macht es wenig Sinn, ihnen zu viel Reim oder Vernunft beizumessen.

Viele modernere Sprachen werfen Ausnahmen für Fehler, damit sie keinen Teil ihres möglichen Antwortbereichs für Fehlercodes kapern müssen. Natürlich gibt es in beiden Fällen Kompromisse.

  • Früher gab es zumindest die Tendenz, 0 als Erfolg, positiv als erfolgreich bei Problemen und negativ als erfolglos zu definieren – zumindest in meinen alten Unix-Zeiten.

    – David Thornley

    4. Dezember 2009 um 18:39 Uhr

  • Dies erklärt nicht die nächste logische Frage: Warum ist EIO nicht negativ?

    – Carl Mastrangelo

    22. März um 0:04 Uhr

  • Haftungsausschluss: Ich habe mich nicht darum gekümmert, dies zu recherchieren. Meine Vermutung: EIO wird mit anderen Funktionen geteilt, von denen einige den Wert zurückgeben, ohne ihn zu negieren. Funktionen ohne positive Erfolgsergebnisse höchstwahrscheinlich.

    – Carl Smotricz

    27. März um 11:42 Uhr

Benutzer-Avatar
DigitalRoss

Ihr Verständnis ist im Großen und Ganzen richtig. Die offensichtliche Interpretation ist die richtige.

Die Standardkonvention unterscheidet sich jedoch geringfügig von Ihrer Formel.

In Unix testet ein Programm, das mit dem Status 0 endet, als Stimmt oder Erfolg zu Dienstprogrammen auf CLI-Ebene wie der Shell. In der Bücherei, -1 ist normalerweise eine Fehlerrückgabe.

Dies führt zu einem allgemeinen Paradigma, in dem >= 0 meint gut und < 0 meint Error. Nichts davon ist in Stein gemeißelt.

Übrigens könnte dies als die klassifiziert werden Sentinel-Muster und man könnte es a nennen Sentinel-Rückkehr. Es ist eigentlich eine Kombination aus einem Sentinel-“Wert” und einem Fehlercode, und es ist einfacher einzugeben und Thread-sicherer zu machen, als an einer Stelle einen Fehlercode und an einer anderen einen Sentinel-Wert für Fehler zurückzugeben.

Wikipedia berichtet, dass a Sentinel-Wert wird verwendet, um eine Schleife zu beenden, aber ich würde denken, dass eine Funktionsrückgabe eine weitaus häufigere Instanz wäre. Niemand ist genau verantwortlich für diese Definitionen.

Benutzer-Avatar
Vestlen

Aus Optimierungssicht ermöglicht die Verwendung negativer Zahlen Unix-basierten Kerneln, anhand von nur einem Vergleich statt zwei nach einem Fehlercode zu suchen.

Funktionen im Kernel geben häufig Fehlercodes anstelle von Zeigern zurück. Das bedeutet, dass sich die Fehlercodes nicht mit gültigen Zeigeradressen überschneiden dürfen, also müssten sie grundsätzlich entweder die niedrigsten vorzeichenlosen Werte sein (>= 0) oder die höchsten (<= unsigned max).

Zeigerwerte prüfen für NULL und für Fehlercodes sind sehr häufige Operationen, daher ist es sinnvoll, sie zu optimieren.

Typischerweise die unteren Werte < 0x8000 sind NULL und die oberen Werte sind Fehlercodes (denken Sie daran -1 wird gespeichert als 0xff...ffder maximal mögliche vorzeichenlose Wert).

Dies bedeutet, dass Sie jeweils einen Vergleich verwenden können, um Folgendes zu überprüfen:

NULL wenn x <= 0x8000 (wahr für 0 bis 0x8000)

ERRNO wenn x >= (unsigned long)(-MAX_ERRNO) (wahr für -1 bis -MAX_ERRNO)

Sie können dies in der err.h-Datei von Linux sehen.

1384950cookie-checkWarum eine negative Fehlernummer zurückgeben? (z. B. Rückgabe -EIO)

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy