2013-11-01 88 views
8

隨着我最近升級到Mac OS X 10.9,默認標準C++庫從libstdC++更改爲libC++。從那以後,我觀察到以下代碼示例中記錄的stringstream運算符>>(double)的意外行爲。istream操作符>> libC++和libstdC++之間的>>(double&val)差異

總之,當double值後面跟一個字母時,libC++似乎在從stringstream中提取double值時會出現問題。

我已經檢查過標準(2003),但如果提取應該在這種情況下工作,我找不到任何特定的信息。

所以我很感激任何輸入,無論這是libC++還是libstdC++的錯誤。

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

編譯與c++ --stdlib=libc++ streamtest.cxx代碼給

'-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 

編譯與c++ --stdlib=libstdc++ streamtest.cxx代碼給

'-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 

編譯器版本是

$ 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

在這兩種情況下,本地都是「C」。 –

回答

2

根據(2011)標準的22.4.2.1.2,它看起來像libstdC++是正確的,libC++是錯誤的。

在階段2,

如果[字符 - nm]的不被丟棄,則進行檢查以確定是否c爲允許作爲返回的轉換指定的輸入字段的下一個字符到階段1 [在這種情況下「%g」 - nm]。如果是這樣,它就是積累的。

%g由於轉換說明不承認dX字符,字符不被累積。它也不會被丟棄(只有組分隔符可以被丟棄)。因此第二階段必須在這一點結束。

然後在階段3中轉換積累的字符。

看起來像libC++在階段2錯誤地積累dX,然後嘗試轉換它們,並且失敗。

+0

我向libC++傢伙報告了這個問題。查看錯誤[17782](http://llvm.org/bugs/show_bug.cgi?id=17782) –

+0

僅在尾部字符爲'A'時出現。'F','I','N' ,'P'和'X'(以及小寫字母相同的字符) –

+0

@MarshallClow:OK,A到F和X可以用十六進制數字出現,它們實際上出現在標準的相關部分,如果那些是唯一的罪魁禍首,那麼看看哪裏出了問題。但是,我和N如何發揮作用? –