2012-06-12 8 views
7

Hier ist ein Beispielcode:Ist das ein Compiler-Bug oder ist es mein Code?

#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; 
} 

wo ich versuche, die < < und >> Betreiber für struct tm zu überlasten! Wenn ich meinen Code mit g ++ und führen Sie es kompilieren, erhalte ich:

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

Perfect!

Aber, wenn ich es mit Klirren ++ kompilieren, erhalte ich:

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

OOPS!

Was ist los? es ist ein Problem mit clang oder es ist die Art, wie ich die iStream verarbeite?

+0

Bei ideone.com [gcc-4.3.4] (http://ideone.com/UDQEm) und [gcc-4.5.1] (http://ideone.com/NXZqK) produzieren Sie die gleiche Ausgabe, die Sie sehen mit Klirren. – Blastfurnace

+0

Funktioniert 'strptime' für Sie wie es ist? Es ist eine Nicht-Standard-Funktion (POSIX) und ich bin mir nicht sicher, ob die libC++ von clang dies unterstützt. – dirkgently

+0

'gcc 4.6.3-1ubuntu5' gibt die _Perfect! _ Ausgabe Reza Berichte auf meinem x86-64 Ubuntu System. – sarnold

Antwort

9

konnte ich diese (g ++ 4.7.0 und Klirren ++ 3.1 mit libC++ - SVN) reproduzieren und eine kurze Debug-Sitzung zeigte, dass Klappern ++ die eofbit nach getline setzt (was normal ist), die dann seekg irgendwie verursacht failbit einstellen . Das klingt wie ein Fehler, da seekg first clears eofbit (§27.7.2.3/41)

zu umgehen, legen Sie is.clear() irgendwo zwischen den getline und den seekg.

+2

PS: Diese Formulierung ist neu in C++ 11, C++ 03 hat das nicht gesagt und es sogar in Zweifel gezogen, dass wir uns von eof abwenden können: [LWG 342] (http: //cplusplus.github. com/LWG/lwg-closed.html # 342) – Cubbi

+3

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

Verwandte Themen