c++ - LWG2349 会有什么影响?

标签 c++ exception istream libstdc++ libc++

虽然 libstdc++ 没有,但 libc++ 确实遵循 the standard which states那路过ios_base::failbit basic_istream::exceptions 对格式化输入没有影响。例如这段代码:

istringstream is{"ASD"};    
double foo;

is.exceptions(istream::failbit);

try {
    is >> foo;
    cout << foo << endl;
} catch(ios_base::failure& fail) {
    cout << "ouch\n";
}

会导致:

我对 LWG2349 的阅读是它会导致basic_istream不要抛出任何格式化的输入。

例如,LWG2349 提议对标准的 27.7.2.3 [istream]/1 进行更改,该标准被引用为引用 the invalidation of a bug that would have made libc++ behave like libstdc++ .更改在下面以粗体和删除线表示:

If an exception , other than the ones thrown from clear(), if any, is thrown during input then ios::badbit is turned on in *this’s error state. (Exceptions thrown from basic_ios<>::clear() are not caught or rethrown.) If (exceptions()&badbit) != 0 then the exception is rethrown.

I understand that basic_istream::clear is what throws in reaction to bad formatted input所以我误读了 LWG2349 还是它实际上会停止 basic_istream抛出任何错误?

最佳答案

排除异常“clear()”抛出的语言的要点是确保if clear() 抛出,因为输入函数调用了 clear(failbit) and (exceptions() & failbit) != 0,然后是 badbit结果未设置。 clear() 将在这种情况下继续抛出,只是不会设置 badbit。

如 LWG2349 的评论中所述,其目的是在用户代码抛出异常时设置 badbit:

PJ and Matt both agree that the intention (of badbit + rethrow) is "to signify an exception arising in user code, not the iostreams package".

现在,什么时候“用户代码”可以在 iostream 机制中抛出异常?一个例子是语言环境 setter/getter :

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() << '\n';
    }
    std::cout
        << ((iss.rdstate() & std::ios_base::eofbit) ? "eof " : "")
        << ((iss.rdstate() & std::ios_base::failbit) ? "fail " : "")
        << ((iss.rdstate() & std::ios_base::badbit) ? "bad " : "")
        << '\n';
}

目前gcc输出:

eof fail

clang 输出:

eof fail

在 LWG2349 之后,正确的行为是设置 badbit 并重新抛出异常:

my_get::do_get
eof bad

关于c++ - LWG2349 会有什么影响?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35088800/

相关文章:

c++ - 海湾合作委员会警告 "set but not used "

c++ - 重载 >> 使用 istream

c++ - 如何以相反的顺序读取 C++ 程序的输入?

EOF : behavior change; work-around? 上的 C++ istream tellg()/fail()

java - 无法在 Eclipse 上编写 Java 8 代码?

c++ - std::vector 推速?

c++ - 为什么在复制赋值之前调用复制构造函数?

c++ - 将 MongoDB C++ 驱动程序升级到 mongocxx-3.1.2

asp.net - Application_Start 中出现间歇性异常 - 如何取消启动应用程序?

mysql - Node MySQL 错误 - 错误 : Cannot enqueue Quit after invoking quit