I stumbled across a difference in behavior between different compilers. Suppose the following code:
#include <sstream>
#include <iostream>
using namespace std;
int main() {
istringstream ss("100");
int val;
ss >> val;
cout << "fail: " << ss.fail() << " eof: " << ss.eof() << endl;
ss >> std::ws;
cout << "fail: " << ss.fail() << " eof: " << ss.eof() << endl;
}
The output generated by VS2019 and Clang 10 with libc++ is:
fail: 0 eof: 1
fail: 1 eof: 1
While VS2015 and GCC 10.2 with libstdc++ generates:
fail: 0 eof: 1
fail: 0 eof: 1
So the question is which implementation is correct? Should std::ws set the failbit when eofbit is already set?
I've looked up std::ws in the standard which says:
30.7.4.4 Standard basic_istream manipulators [istream.manip]
template<class charT, class traits> basic_istream<charT, traits>& ws(basic_istream<charT, traits>& is);
Effects: Behaves as an unformatted input function (30.7.4.3), except that it does not count the number of characters extracted and does not affect the value returned by subsequent calls to is.gcount(). After constructing a sentry object extracts characters as long as the next available character c is whitespace or until there are no more characters in the sequence. Whitespace characters are distinguished with the same criterion as used by sentry::sentry (30.7.4.1.3). If ws stops extracting characters because there are no more available it sets eofbit, but not failbit.
So at the end it is explicitly stated that it sets eofbit, but not failbit when no characters are available. But then it also behaves as an unformatted input function, which creates an sentry object. The sentry constructor then will call is.setstate(failbit) when is.good() is false. So in a way both implementations are not completly wrong. Can someone who better understands standardese clarify which bevavior is correct and where I should file a bug?
failbit should be set. It's done by sentry object, what ws constructs first thing.
[istream::sentry]/2
explicit sentry(basic_istream<charT, traits>& is, bool noskipws = false);
Effects: Ifis.good()isfalse, callsis.setstate(failbit). Otherwise, ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With