C ++ Äquivalent von Perror?

8

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 von ec anzugeben, die den spezifischen Grund identifizieren   für den Fehler. [ Hinweis - Fehler beim Betrieb   System würde in der Regel als system_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 als error_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?

    
user5371056 24.09.2015, 08:04
quelle

2 Antworten

1

Ich stimme dir nicht auf

zu
  

perror 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 ersetzt durch andere in C ++ - Bibliothek. Wenn jedoch nichts hinzuzufügen ist (cernno, cmath, csignal usw.), werden die Funktionen aus der C-Standardbibliothek einfach in C ++ eins eingefügt.

    
Serge Ballesta 24.09.2015 08:42
quelle
0

POSIX hat strerror_r() und Windows hat strerror_s() . Beachten Sie, dass dort mehrere inkompatible Funktionen namens strerror_r() vorhanden waren, verwenden Sie also Ihre Feature-Test-Makros.

    
Davislor 24.09.2015 08:27
quelle

Tags und Links