2013-11-01 17 views
8

Mit meinem letzten Upgrade auf Mac OS X 10.9 hat sich die Standard-C++ - Standardbibliothek von libstdC++ in libC++ geändert. Seitdem beobachte ich das unerwartete Verhalten des Stringstream-Operators >> (doppelt), das im folgenden Codebeispiel dokumentiert ist.Diskrepanz zwischen dem istream-Operator >> (double & val) zwischen libC++ und libstdC++

Zusammenfassend scheint die libC++ Probleme beim Extrahieren von doppelten Werten aus Stringstreams zu haben, wenn auf den doppelten Wert ein Buchstabe folgt.

Ich habe bereits den Standard überprüft (2003), aber ich kann keine spezifischen Informationen finden, ob die Extraktion in diesem Fall funktioniert oder nicht.

So wäre ich dankbar für jede Eingabe, ob dies ein Fehler in libC++ oder libstdC++ ist.

#include <sstream> 
#include <iostream> 

using namespace std; 

void extract_double(const string & s) 
{ 
    stringstream ss; 
    double d; 

    ss << s; 
    ss >> d; 
    if(!ss.fail()) 
    cout << "'" << ss.str() << "' converted to " << d << endl; 
    else 
    cout << "'" << ss.str() << "' failed to convert to double" << endl; 
} 

int main() 
{ 
    extract_double("-4.9"); 
    extract_double("-4.9 X"); 
    extract_double("-4.9_"); 
    extract_double("-4.9d"); 
    extract_double("-4.9X"); 
} 

Kompilieren des Codes mit c++ --stdlib=libc++ streamtest.cxx gibt

'-4.9' converted to -4.9 
'-4.9 X' converted to -4.9 
'-4.9_' converted to -4.9 
'-4.9d' failed to convert to double 
'-4.9X' failed to convert to double 

Kompilieren des Codes mit c++ --stdlib=libstdc++ streamtest.cxx gibt

'-4.9' converted to -4.9 
'-4.9 X' converted to -4.9 
'-4.9_' converted to -4.9 
'-4.9d' converted to -4.9 
'-4.9X' converted to -4.9 

Compiler Version ist

$ c++ --version 
Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn) 
Target: x86_64-apple-darwin13.0.0 
Thread model: posix 
+0

Die lokale ist in beiden Fällen "C". –

Antwort

2

Es sieht so aus, dass libstdC++ richtig ist und libC++ gemäß 22.4.2.1.2 des (2011) Standards falsch ist.

In Stufe 2,

Wenn sie [die Zeichen - nm] nicht verworfen wird, dann wird eine Prüfung vorgenommen zu bestimmen, wenn c als das nächste Zeichen eines Eingabefeldes des Konvertierungsspezifizierer erlaubt wird zurückgegeben nach Stufe 1 ["% g" in diesem Fall - nm]. Wenn ja, ist es angesammelt.

Da %g Konvertierungsspezifizierer nicht d oder X Zeichen nicht zulassen, wird das Zeichen nicht akkumuliert. Es wird auch nicht verworfen (nur Gruppentrennzeichen können verworfen werden). Daher muss Stufe 2 an dieser Stelle enden.

Dann in Stufe 3 akkumulierte Zeichen umgewandelt werden.

Es sieht aus wie LibC++ fälschlicherweise d und X in Stufe 2 akkumuliert, dann versucht, sie zu konvertieren, und dies schlägt fehl.

+0

Ich habe das Problem an die libC++ Jungs gemeldet. Siehe Bug [17782] (http://llvm.org/bugs/show_bug.cgi?id=17782) –

+0

Wird nur angezeigt, wenn das nachfolgende Zeichen 'A' ist. 'F', 'I', 'N' , 'P' und 'X' (und die gleichen Zeichen in Kleinbuchstaben) –

+0

@MarshallClow: OK, A bis F und X können in hexadezimalen Zahlen erscheinen, und sie erscheinen tatsächlich im relevanten Teil des Standards, so könnte man wahrscheinlich Sehen Sie, wo die Dinge schief gelaufen sind, wenn das die einzigen Schuldigen waren. Aber wie kamen I, N und P ins Spiel? –