Should extracting from a stream using the std::ws manipulator ever raise the fail bit? In the following code, a Clang-compiled (within Xcode 4.5.1) program fails the final assertion. Evidently s >> std::ws
at EOF causes a fail. Yet GCC 4.7.2 passes the assertion. Which is correct?
#include <iostream>
#include <sstream>
#include <cassert>
int main(int argc, const char * argv[])
{
{
// Read string with trailing ws.
std::istringstream s( "test " );
std::string test;
s >> std::ws;
assert( !s.fail() ); // No ws to skip, but no failure.
s >> test;
assert( test == "test" );
assert( !s.fail() );
s >> std::ws;
assert( !s.fail() ); // No prob skipping trailing ws.
}
{
// Retry with no trailing ws.
std::istringstream s( "test" );
std::string test;
s >> std::ws;
assert( !s.fail() ); // No ws to skip, but no failure.
s >> test;
assert( test == "test" );
assert( !s.fail() );
s >> std::ws;
assert( !s.fail() ); // CLANG: Skipping absent ws at eof raises failbit.
}
return 0;
}
C++11, §27.7.2.4/1:
If
ws
stops extracting characters because there are no more available it setseofbit
, but notfailbit
.
So, the ws
manipulator doesn't set failbit
directly. However, as Marshall Clow points out in his answer, it doesn't have to--it is required to create a sentry object, and the sentry object is required to set the failbit if !stream.good()
.