istream der Diskrepanz zwischen libc ++ und libstdc ++

8

Das folgende (Spielzeug-) Programm gibt verschiedene Dinge zurück, wenn es mit libstdc ++ und libc ++ verknüpft wird. Ist das ein Fehler in libc ++ oder verstehe ich nicht, wie istream () funktioniert? Ich habe versucht, es mit g ++ auf Linux und Mac OS X und Mac OS X, mit und ohne -std = C ++ 0 x. Es war mein Eindruck, dass eof () erst dann wahr zurückgibt, wenn ein Versuch (durch get () oder etwas anderes) fehlschlägt. So verhält sich libstdc ++, verhält sich aber nicht wie libc ++.

%Vor%     
zaphoyd 25.01.2012, 14:53
quelle

4 Antworten

4

Dies war ein libc ++ Bug und wurde behoben, wie Cubbi bemerkte. Mein Fehler. Details sind hier:

Ссылка

    
Howard Hinnant 26.01.2012, 15:14
quelle
5

EDIT : Dies lag an der Art und Weise, wie ältere Versionen von libc ++ den C ++ - Standard interpretierten. Die Interpretation wurde in der LWG-Ausgabe 2036 diskutiert, es wurde entschieden falsch sein und libc ++ wurde geändert.

Aktuelle libc ++ liefert die gleichen Ergebnisse wie libstdc ++.

alte Antwort:

Ihr Verständnis ist richtig.

istream::get() macht Folgendes:

  1. Ruft good() auf und setzt failbit , wenn es false zurückgibt (dies fügt ein Failbit zu einem Stream hinzu, der ein anderes Bit gesetzt hat), ( §27.7.2.1.2[istream::sentry]/2 )
  2. Spült, was immer nötig ist () falls nötig
  3. Wenn good() zu diesem Zeitpunkt false ist, wird eof zurückgegeben und nichts weiter ausgeführt.
  4. Extrahiert ein Zeichen als ob , indem es rdbuf()->sbumpc() oder rdbuf()->sgetc() ( §27.7.2.1[istream]/2 )
  5. aufruft
  6. Wenn sbumpc() oder sgetc() eof zurückgibt, wird eofbit festgelegt. ( §27.7.2.1[istream]/3 ) und failbit ( §27.7.2.2.3[istream.unformatted]/4 )
  7. Wenn eine Ausnahme ausgelöst wurde, wird badbit ( §27.7.2.2.3[istream.unformatted]/1 ) gesetzt und erneut ausgeführt, falls erlaubt.
  8. Aktualisiert gcount und gibt das Zeichen zurück (oder eof, wenn es nicht erhalten werden konnte).

(Kapitel zitiert aus C ++ 11, aber C ++ 03 hat alle die gleichen Regeln, unter §27.6. *)

Sehen wir uns nun die Implementierungen an:

libc ++ (aktuelle svn-Version) definiert den relevanten Teil von get () als

%Vor%

libstdc ++ (wie mit gcc 4.6.2 ausgeliefert) definiert den gleichen Teil wie

%Vor%

Wie Sie sehen, rufen beide Bibliotheken sbumpc() auf und setzen eofbit genau dann, wenn sbumpc () eof zurückgibt.

Ihr Testfall erzeugt die gleiche Ausgabe für mich mit den neuesten Versionen beider Bibliotheken.

    
Cubbi 25.01.2012 18:03
quelle
1

Der Wert von s.eof() ist im zweiten Aufruf nicht angegeben - das kann sein wahr oder falsch, und es könnte nicht einmal konsistent sein. Alles was du sagen kannst ist Wenn s.eof() wahr zurückgibt, werden alle zukünftigen Eingaben fehlschlagen (aber wenn es gibt false zurück, es gibt keine Garantie, dass zukünftige Eingaben erfolgreich sein werden). Nach dem Fehler ( s.fail() ), wenn s.eof() wahr zurückgibt, ist es wahrscheinlich (aber nicht 100% sicher), dass der Fehler auf das Ende der Datei zurückzuführen war. Es ist es wert unter Berücksichtigung des folgenden Szenarios:

%Vor%

Auf meinem Rechner sind beide Zeilen "TT" , trotz der Tatsache, dass der erste fehlgeschlagen, weil keine Daten vorhanden waren (Ende der Datei), der zweite, weil der Gleitkommawert wurde falsch formatiert.

    
James Kanze 25.01.2012 15:27
quelle
0

eofbit ist gesetzt, wenn es eine Operation gibt, die versucht, über das Ende der Datei hinaus zu lesen, die Operation kann nicht fehlschlagen (wenn Sie eine Ganzzahl lesen und es kein Ende der Zeile hinter der Ganzzahl gibt, erwarte ich, dass efbit gesetzt wird aber das Lesen der ganzen Zahl zum Erfolg). I.E. Ich bekomme und erwarte FT für

%Vor%

Hier erwarte ich nicht, dass istream :: get versuchen soll, nach dem zurückgegebenen Zeichen zu lesen (dh ich erwarte nicht, dass es so lange hängt, bis ich die nächste Zeile lese, wenn ich a \ n damit lese), so scheint libstd ++ in der Tat, zumindest in einem QOI POV.

Die Standardbeschreibung für istream :: get sagt nur "extrahiert ein Zeichen c, falls vorhanden" ohne zu beschreiben, wie und so scheint es das Verhalten von libc ++ nicht zu verhindern.

    
AProgrammer 25.01.2012 15:27
quelle

Tags und Links