Soweit mir bekannt ist, sind meine beiden Optionen zur Behandlung von Stream-Fehlern perror
und Stream-Ausnahmen. Beide Optionen sind unerwünscht. Hier ist warum:
perror
std::strerror
gibt eine implementierungsdefinierte Nachricht zurück. Diese Nachricht ist nicht immer auf allen Systemen nützlich
std::strerror
ist nicht threadsicher
Der von std::strerror
zurückgegebene Zeiger kann ungültig gemacht werden
Die C-Bibliothek ist in C ++ technisch "veraltet". Es gibt fast immer ein C ++ - ähnliches Äquivalent. Es gibt keinen Grund, warum ich mich auf POSIX und C verlassen sollte, wenn es ein mögliches C ++ Äquivalent gibt.
Stream-Ausnahmen
Ausnahmen sind nicht für jedes Programm geeignet
Während std::strerror
manchmal eine nützliche Fehlermeldung liefert, bieten Stream-Ausnahmen never eine nützliche Fehlermeldung. Mit f.exceptions(f.failbit)
ist sowohl für das Nichtöffnen einer Datei als auch das Fehlschlagen des Extrahierens die Ausnahme std::ios_base::failure
und what()
" basic_ios::clear
".
system_error
Durch den Austausch von std::ios_base::failure
mit std::system_error
werden genau die gleichen Ergebnisse erzielt. Wenn wir uns N2769: Detailed Reporting for Input/Output Library Errors (Revision 2)
ansehen, können wir das tun sehen warum:
Beim Auslösen von
ios_base::failure
Ausnahmen sind Implementierungen ermutigt, Werte vonec
anzugeben, die den spezifischen Grund identifizieren für den Fehler. [ Hinweis - Fehler beim Betrieb System würde in der Regel alssystem_category
Fehler mit einem gemeldet werden Fehlerwert der Fehlernummer, die vom Betriebssystem gemeldet wurde. Fehler, die sich aus der Stream-Bibliothek ergeben, sind typischerweise gemeldet alserror_code(ioerrc::stream, iostream_category
) - end beachten Sie ].Die obige Formulierung bietet nur normativen Anreiz für die Umsetzer, das Richtige zu tun, und stützt sich somit auf Marktkräfte und die gute Absicht der Implementierer, Ergebnisse zu produzieren, die nützlich sind Benutzer. Alles Stärkere (wie zum Beispiel das Wechseln zu "ermutigt") "soll") würde viel zusätzliche Spezifikation erfordern und ist jenseits der Umfang dessen, was die LWG für C ++ 0x realistisch angehen kann.
Die Alternative ist, sich potenziell auf eine sperrige Third-Party-Bibliothek zu verlassen (ich schaue auf Sie Boost) oder sie manuell zu rollen (was Sie nie tun wollen, wenn Sie nicht wissen, was Sie tun.) Ich bin Suche nach der C ++ - Standardbibliothek, um dies zu tun. Gibt es welche?
Ich stimme dir nicht auf
zuperror et alii sind Mitglied der C-Standardbibliothek und daher technisch veraltet (*).
Nun, selbst auf cplusplus.com, wenn nicht eine offizielle Dokumentationsquelle, sehe ich für errno:
C ++ 11 erweitert die Basismenge von Werten, die in diesem Header definiert werden müssen ... In C ++ wird errno immer als Makro deklariert, aber in C kann es auch als int-Objekt mit externer Verknüpfung implementiert werden.
Mein Verständnis dieser Sätze ist, dass errno
immer noch in C ++ 11 berücksichtigt wird!
Ich kann sogar später sehen
Bibliotheken, die Multithreading unterstützen, müssen errno pro Thread implementieren: Jeder Thread hat sein eigenes lokales errno. Dies ist eine Anforderung in Bibliotheken, die den C11- und C ++ 11-Standards entsprechen.
bedeutet, dass, auch wenn strerror()
nicht threadsicher ist, errno
in jeder C ++ 11-kompatiblen Implementierung enthalten ist.
Es ist jetzt an Ihnen, std::strerror
in einer synchronisierten Funktion zu verwenden (zum Beispiel mit einem Mutex geschützt), um ein std::string
zu erstellen, wenn Sie möchten. Aber selbst wenn jede Dokumentation von strerror
angibt, dass sie einen statischen Puffer verwendet, der überschrieben werden könnte (deshalb definiert Posix 1 strerror_r), konnte ich keine Warnung finden, da perror
nicht threadsicher ist.
(*) Meine Meinung besteht darin, dass immer dann, wenn OO und Templates ein netteres Interface (iostream vs stdio.h oder string vs. string.h) ergeben, Elemente der C-Bibliothek
Tags und Links c++ error-handling