2012-06-12 13 views
7

Aquí es un ejemplo de código:¿Es esto un error del compilador o es mi código?

#include <iostream> 
#include <stdexcept> 
#include <cstring> 
#include <ctime> 
#include <sstream> 

using std::cout; 
using std::endl; 

std::size_t const BUF_SIZE(1000); 

std::ostream& operator<<(std::ostream& os, std::tm const& rhs) 
{ 
    os << asctime(&rhs); 
    return os; 
} 

std::istream& operator>>(std::istream& is, std::tm& rhs) 
{ 
    while (is.peek() == ' ' || is.peek() == '\t') 
    { 
     is.get(); 
    } 
    std::streampos curPos = is.tellg(); 
    char buf[BUF_SIZE]; 
    is.getline(buf, BUF_SIZE); 
    char* ptr = strptime(buf, "%D %T", &rhs); 
    if (ptr == 0) 
    { 
     throw std::runtime_error("strptime() failed!"); 
    } 
    std::size_t processed = ptr - buf; 
    is.seekg(curPos + static_cast<std::streampos>(processed)); 
    return is; 
} 

int main() 
{ 
    std::istringstream is("10101 07/09/12 07:30:00 123.24"); 
    int uuid(0); 
    double price(0); 
    std::tm ptime; std::memset(&ptime, 0, sizeof(tm)); 

    is >> uuid >> ptime >> price; 
    cout << "UUID: " << uuid << endl; 
    cout << "Time: " << ptime; 
    cout << "Price: " << price << endl; 
} 

donde yo estoy tratando de sobrecargar los < < y >> para los operadores estructura tm! Si puedo compilar mi código con g ++ y ejecutarlo, me sale:

UUID: 10101 
Time: Sun Jul 9 07:30:00 2012 
Price: 123.24 

perfecto!

Pero, si puedo compilar usando sonido metálico ++, me sale:

UUID: 10101 
Time: Sun Jul 9 07:30:00 2012 
Price: 0 

OOPS!

¿Qué está pasando? Es esto un problema con clang o es la forma en que estoy procesando el istream?

+0

En ideone.com [gcc-4.3.4] (http://ideone.com/UDQEm) y [gcc-4.5.1] (http://ideone.com/NXZqK) producen el mismo resultado que usted ve con clang. – Blastfurnace

+0

¿'strptime' funciona como está en clang para usted? Es una función no estándar (POSIX) y no estoy seguro de si la compatibilidad de clang es compatible. – dirkgently

+0

'gcc 4.6.3-1ubuntu5' le da a _Perfect! _ Informes de salida Reza en mi sistema Ubuntu x86-64. – sarnold

Respuesta

9

que era capaz de reproducir este (g ++ 4.7.0 y sonido metálico ++ 3.1 con libC++ - SVN) y una sesión de depuración breve mostraron que tañido ++ establece el eofbit después getline (que es normal), que a su vez causa de algún modo seekg para establecer failbit . Esto suena como un error, dado que seekg first clears eofbit (§27.7.2.3/41)

Para evitar, inserte is.clear() en cualquier lugar entre el getline y la seekg.

+2

PD: esta redacción es nueva en C++ 11, C++ 03 no dice eso y de hecho hace que sea dudoso que podamos buscar fuera de eof: [LWG issue 342] (http: //cplusplus.github. com/LWG/lwg-closed.html # 342) – Cubbi

+3

PS/2: Enviado: http://llvm.org/bugs/show_bug.cgi?id=13089 – Cubbi

Cuestiones relacionadas