I strongly believed that std::basic_istream::operator>>
is "transaction safe", i.e. if it fails, it leaves its operand unchanged. So, I was expected that for the following code
#include <iostream>
#include <sstream>
int main()
{
std::stringstream ss("a");
int i = 42;
ss >> i; // extraction fails
std::cout << i; // modifies i, WHY?!
}
the value of i
would stay 42
. However, starting from C++11 this doesn't seem to be the case anymore, and the operand is zeroed on failure. Quoting from cppreference.com
(emphasize mine)
If extraction fails (e.g. if a letter was entered where a digit is expected),
value
is left unmodified andfailbit
is set. (until C++11)If extraction fails, zero is written to
value
andfailbit
is set. If extraction results in the value too large or too small to fit in value,std::numeric_limits<T>::max()
orstd::numeric_limits<T>::min()
is written andfailbit
flag is set. (since C++11)
Can anyone explain what is the reason for this modification? I find the behaviour undesirable, to say the least. Even if I compile with -std=c++98
, gcc5.3 and clang3.6 still behave C++11-compliant.