Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Another istream discrepancy between libstdc++ and libc++

This simple code:

#include <iostream>
#include <sstream>
int main()
{
   float x = 0.0;
   std::stringstream ss("NA");
   ss >> x;

    std::cout << ( ss.eof() ? "is" : "is not") << " at eof; x is " << x << std::endl;
}

returns different results, depending on which library I choose (I'm running clang from xcode 5 on OSX 10.9):

clang++ -std=c++11 -stdlib=libstdc++ -> not at eof
clang++ -stdlib=libstdc++ -> not at eof
/usr/bin/g++-4.2 -> not at eof

clang++ -std=c++11 -stdlib=libc++ -> at eof
clang++ -stdlib=libc+ -> at eof

It seems to me that if I try to read an alphabetic character into a float, the operation should fail, but it shouldn't eat the invalid characters - so I should get fail() but not eof(), so this looks like a bug in libc++.

Is there a c++ standard somewhere that describes what the behavior should be?

p.s. I've expanded the original test program like so:

#include <iostream>
#include <sstream>
int main()
{
   float x = 0.0;
   std::stringstream ss("NA");
   ss >> x;
    std::cout << "stream " << ( ss.eof() ? "is" : "is not") << " at eof and " << (ss.fail() ? "is" : "is not") << " in fail; x is " << x << std::endl;
    if (ss.fail())
    {
        std::cout << "Clearing fail flag" << std::endl;
        ss.clear();
    }
   char c = 'X';
    ss >> c;
    std::cout << "Read character: \'" << c << "\'" << std::endl;
}

and here's what I see:

With libc++:

stream is at eof and is in fail; x is 0
Clearing fail flag
Read character: 'X'

with stdlibc++:

stream is not at eof and is in fail; x is 0
Clearing fail flag
Read character: 'N'

p.p.s. As described in the issue that n.m. links to, the problem doesn't occur if the stringstream is set to "MA" instead of "NA". Apparently libc++ starts parsing the string, thinking it's going to get "NAN" and then when it doesn't, it gets all upset.

like image 829
Betty Crokker Avatar asked Jan 22 '26 01:01

Betty Crokker


1 Answers

In this case, you should get fail, but not eof. Basically, if, after failure, you can clear the error and successfully do a get() of a character, you should not get eof. (If you cannot successfully read a character after clear(), whether you get eof or not may depend on the type you were trying to read, and perhaps in some cases, even on the implementation.)

like image 193
James Kanze Avatar answered Jan 24 '26 20:01

James Kanze