2017-12-05 3 views
0

hier gefangen werden können, ist ein einfaches Beispiel für die AnwendungSchub time_facet eine Ausnahme verursacht, die nicht

#include <string> 
#include <boost/date_time/posix_time/posix_time.hpp> 

int main() 
{ 
    try 
    { 
     auto date = boost::posix_time::microsec_clock::local_time(); 

     // boost::posix_time::time_facet* facet = new boost::posix_time::time_facet("%d-%b-%Y %H:%M:%S"); --> this format works 
     boost::posix_time::time_facet* facet = new boost::posix_time::time_facet("%d-%b-%Y %k:%M:%s"); // --> this format causes an exception that can't be handled 
     std::stringstream ss; 

     ss.imbue(std::locale(ss.getloc(), facet)); 
     //ss.exceptions(std::ios::badbit | std::ios::failbit); 
     ss << date; // --> exception occurs here - It can't be caught. 
     std::cout << ss.str() << std::endl; 
    } 
    catch (const std::exception& ex) 
    { 
     std::cerr << "std::exception " << ex.what() << std::endl; 
    } 
    catch (const boost::exception&) 
    { 
     std::cerr << "boost::exception " << std::endl; 
    } 
    catch (...) 
    { 
     std::cerr << "unknown exception" << std::endl; 
    } 

    return 0; 
} 

Das Problem ist, mit einem bestimmten Format an die Facette bestanden - entweder% k oder% l das Problem verursachen. Wenn ein Datum in diesem Format formatiert wird, gibt es eine Ausnahme. Die Exception wird nicht vom Exception-Handler abgefangen - das Programm wird beendet!

Ich erstelle eine Bibliotheksfunktion, so dass ich annehmen muss, dass ungültige Formatzeichenfolgen vorkommen. Ich bin in Ordnung mit einer Ausnahme - ich muss nur in der Lage sein, damit umzugehen und den Fehler zu melden oder zu bestätigen, dass die Facette gültig ist, bevor ich sie benutze.

Dies geschieht unter Windows 10. Der Fehler ist in der Funktion wcsftime. Auch wcsftime ist eine breite Char-Funktion, und ich verwende 8 Bit Char. Die Anwendung wird in Visual Studio 2017 mit MultiByte-Zeichensatz anstelle von Unicode kompiliert.

Error from debugger

Das Problem tritt in dem Debugger mit der obigen Aussage. Das Ausführen des Releasebuilds über die Befehlszeile führt zum Absturz der Anwendung und zum Aufrufen des Windows-Dialogfelds "Anwendung hat aufgehört zu arbeiten".

Die Boost-Version ist 1.65.1

Was mache ich falsch?

+2

Das ist eine Behauptung, keine Ausnahme. Eine Behauptung bedeutet einen Fehler. – chris

+0

Sie können keine Assertionsfehler abfangen. (Nun, Sie könnten wahrscheinlich, aber nicht wie Ausnahmen, und Sie sollten nicht.) Behauptungen sind da, um Programmierer Fehler zu erkennen, Sie sollen den Fehler beheben, nicht zur Laufzeit wiederherstellen. –

+0

Ich sehe keine Möglichkeit, vorher zu prüfen, ob ein Format gültig ist, durch Boost oder durch 'strftime'. Es ist bedauerlich, dass es eine Behauptung geben würde, die keinen einfachen Weg hat, sie zu verhindern. Es ist wahrscheinlich, dass das Format eine fest codierte Sache war und nicht etwas, das mit unbekannter Eingabe erstellt wurde. Von der Zusicherungsbedingung scheint es, dass die Implementierung es auch nicht an der Vorderseite prüft, wahrscheinlich, weil es einen Teil der Arbeit duplizieren würde, den die Funktion bereits zu tun hat. – chris

Antwort

0

Eines der Dinge, die Sie falsch machen, ist die Verwendung von MBCS ... Definitiv nicht zu empfehlen. Das native String-Format von Windows ist UNICODE, und alle mit A endenden Funktionen transformieren die Eingabezeichenfolgen und rufen dann ihre W-Gegenstücke auf.

Warum der Anruf zu neuen? Für das Zeitformat ist auf dem Stack sicher genug Platz.

Wie auch immer, der Dialog, den Sie sehen, zeigt eine Assertion fehlgeschlagene Nachricht. Es ist ein Debug-Breakpoint (__asm int 3;), keine Ausnahme. Es ist auch nur in der Debug-Version der Laufzeitbibliothek vorhanden.

Sie sollten versuchen, einen Release-Build zu kompilieren, oder klicken Sie auf die Schaltfläche "Ignorieren" und beobachten Sie, wie Ihre App die Ausnahme abfängt.

[Bearbeiten] Nach der Untersuchung verursacht strftime() die App zum Absturz. Eine ungültige Formatzeichenfolge wird von der C-Laufzeitbibliothek als schwerwiegender Fehler angesehen. Warum nicht, aber so ist es.

+0

Das Klicken auf die Schaltfläche "Ignorieren" führt zu einem Absturz beim Debugging. Außerdem habe ich sowohl Unicode als auch MBCS ausprobiert, da ich dachte, dass dies das Problem gewesen sein könnte. –

+0

Lassen Sie sich eine Notiz machen, die wie folgt lauten soll: "Die Übergabe eines schlecht formatierten Formatierungsstrings an den Konstruktor von boost :: posix_time :: time_facet führt zu undefiniertem Verhalten." Wie weiter durch die Behauptung angezeigt wird, bricht der Code ab. –

Verwandte Themen