The point of the language excluding exceptions "thrown from clear()
" is to ensure that if clear()
throws, because an input function has called clear(failbit)
and (exceptions() & failbit) != 0
, then badbit is not set as a result. clear()
will continue to throw in that case, it just will not set badbit.
As described in the commentary to LWG2349, the intention is that badbit is set when an exception is thrown from user code:
PJ and Matt both agree that the intention (of badbit + rethrow) is "to signify an exception arising in user code, not the iostreams package".
Now, when can an exception be thrown by "user code" but within the iostreams machinery? One example would be by the locale getters:
struct my_get : std::num_get<char> {
using iter_type = std::istreambuf_iterator<char>;
iter_type do_get(iter_type, iter_type, std::ios_base&, std::ios_base::iostate&, bool&) const override {
throw std::logic_error{"my_get::do_get"};
}
};
int main() {
std::istringstream iss;
iss.imbue({std::locale{}, new my_get});
iss.exceptions(std::ios_base::failbit | std::ios_base::badbit);
try {
bool b;
iss >> b;
} catch (std::exception& ex) {
std::cout << ex.what() << '
';
}
std::cout
<< ((iss.rdstate() & std::ios_base::eofbit) ? "eof " : "")
<< ((iss.rdstate() & std::ios_base::failbit) ? "fail " : "")
<< ((iss.rdstate() & std::ios_base::badbit) ? "bad " : "")
<< '
';
}
At present, gcc outputs:
eof fail
clang outputs:
eof fail
After LWG2349, the correct behavior is to set badbit and rethrow the exception:
my_get::do_get
eof bad
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…