简体   繁体   中英

istream behavior change in C++ upon failure

Take from: cppreference

Until C++11:

If extraction fails (eg if a letter was entered where a digit is expected), value is left unmodified and failbit is set.

Since C++11:

If extraction fails, zero is written to value and failbit is set. If extraction results in the value too large or too small to fit in value, std::numeric_limits<T>::max() or std::numeric_limits<T>::min() is written and failbit flag is set.

Due to this change, this means that the following snippet:

int x = 1;
std::cin >> x;
return x;

in the event that the numerical conversion fails, will return 1 before C++11, and 0 otherwise.

Why would the standard committee introduce such a subtle breaking change? Or rather, what kind of code was possible prior to C++11 that warranted this change?

It seems as originally specified, the operator>> s were broken in some cases (ie strictly speaking couldn't exist). This is the "fix".

In a draft from early 2011, The Standard is basically the same in this regard as it was in 2003. However, in a library defect report opened by Matt Austern (in 1998!), num_get<>::get() doesn't exist for short and int . So they were changed to use the long version, and check the read number falls within the correct range.

The defect report is here .

(Doesn't really explain why they didn't think they could keep the originally intended behaviour, but it is why this part of The Standard was changed.)

It's more the C++ way of doing things to store zero in the non- const reference input x then returning the original value in case of error.

In order to keep the original value in case of an error condition the library would have to work with a temporary. It can't simply use the space provided by x without storing the original value somewhere. Then it might also have to do a copy to x at some point once the error conditions are known. How else would you get the original value if there's an error or the read input otherwise. So everyone pays the price regardless of whether they want this behavior or not.

So returning the original value in case of error isn't C++ at all. If you want that behavior simply pay for it yourself - create a temporary and pass its non- const reference to operator>> , something like:

int x = 1;
int temp;
if (std::cin >> temp) 
    x = temp;
return x;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM