2013-02-11 6 views
11

Intuitivamente, a giudicare dalle specifiche C++, mi sembra che istream::putback(c) debba sempre organizzare il buffer di input in modo tale che la prossima chiamata a istream::peek() debba leggere il carattere c. Non è corretto? Chiedo perché l'ultima versione di libC++ di spedizione con Xcode 4.6 sembra non applicare questo comportamento in tutti i casi, in particolare quando l'ultimo carattere è in EOF. Lo stesso vale se si utilizza unget() anziché putback(c).Non dovrebbe istream :: peek() restituire sempre ciò che hai appena messo()?

Il comportamento di libC++ è corretto oppure il mio intuito su come putback()/unget() dovrebbe funzionare correttamente?

Considerare questo codice di esempio, che funziona con libstdC++ ma non con libC++ (l'asserzione fallisce).

#include <sstream> 
#include <cassert> 

int main(int argc, const char * argv[]) 
{ 
    std::istringstream in("[Test]"); 

    while(in) 
    { 
     int c = in.get(); 
     if(c == ']') 
     { 
      in.putback(c); 
      assert(in.peek() == c); // Fails with libc++. Succeeds with libstdc++. 
      break; 
     } 
    } 

    return 0; 
} 
+2

C'è uno di 'eofbit',' failbit', 'badbit' impostato dopo' putback (c) '? (Per riferimento: con libstdC++ 4.7, nessuno di questi è impostato, lo stream è 'good()'.) – us2012

+0

+1 a entrambe le risposte. Sembra un bug in libC++ corretto in r162608. –

risposta

6

C'è stato effettivamente un cambiamento alla funzione putback in C++ 11:

§27.7.2.3/34

basic_istream<charT,traits>& putback(char_type c);

Effetti: si comporta come un ingresso non formattato funzione (come descritto in 27.7.2.3, paragrafo 1), tranne per il fatto che la funzione cancella prima eofbit. ...

Dove la seconda metà della frase non esisteva in C++ 03.

Quindi potrebbe dipendere se i compilatori hanno implementato completamente questa modifica o se si utilizzano le opzioni richieste (-std=C++11?).

4

Bo Persson ha ragione sugli standard. Probabilmente stai usando una versione precedente di libC++ (il tuo problema è nel bugtracker LLVM, vedi sotto).

La modifica è stata introdotta nella revisione 162.108:

--- istream  (revision 162607) 
+++ istream  (revision 162608) 
@@ -1263,6 +1263,7 @@ 
    try 
    { 
#endif // _LIBCPP_NO_EXCEPTIONS 
+  this->clear(this->rdstate() & ~ios_base::eofbit); 
     sentry __sen(*this, true); 
     if (__sen) 
     { 

Il registro riguardante il cambiamento:

$ svn log -r 162608

--------- -------------------------------------------------- ------------- r162608 | hhinnant | 2012-08-25 00:03:03 +0200 (Sab, 25 ago 2012) | 1 riga

Avere basic_istream seekg, putback e deselezionare il primo eofbit chiaro. Correzioni http://llvm.org/bugs/show_bug.cgi?id=13089.

Problemi correlati