简体   繁体   English

C ++方法ostream :: exceptions(iostate状态)的行为应该是什么?

[英]What is the behavior of the C++ method ostream::exceptions(iostate state) supposed to be?

I'm in the process of writing my own output streaming library and I'm trying to mimic std::ostream behaviors where it doesn't conflict with the new behaviors I'm trying to achieve. 我正在编写自己的输出流库,并且正在尝试模仿std :: ostream行为,使其与我尝试实现的新行为不冲突。 Currently I'm trying to mimic this interface inherited from ios: 目前,我正在尝试模仿从ios继承的此接口:

std::ostream::exceptions(ios::iostate state)

According to cplusplus.com : 根据cplusplus.com

"this method sets a new exception mask for the stream and clears the stream's error state flags (as if member clear() was called)." “此方法为流设置新的异常掩码,并清除流的错误状态标志(就像调用了成员clear()一样)。”

It wasn't clear to me whether this meant all flags would be cleared or only the ones being set in the exceptions mask, so I wrote a test program but got quite unexpected results. 我不清楚这是否意味着将清除所有标志还是仅清除在异常掩码中设置的标志,所以我编写了一个测试程序,但结果出乎意料。 Here's the program: 这是程序:

#include <sstream>
#include <iostream>

using namespace std;
int main(int argc, char** argv)
{
    ostringstream oss;
    try
    {
        cout << "            badbit           = " << ios::badbit        << "\n";
        cout << "            eofbit           = " << ios::eofbit        << "\n";
        cout << "            failbit          = " << ios::failbit       << "\n\n";

        cout << "            oss.rdstate()    = " << oss.rdstate()      << "\n";
        cout << "            oss.exceptions() = " << oss.exceptions()   << "\n\n";

        cout << "executing:  oss.setstate(ios::badbit | ios::failbit);" << "\n";
        oss.setstate(ios::badbit | ios::failbit);
        cout << "            oss.rdstate()    = " << oss.rdstate()      << "\n";
        cout << "            oss.exceptions() = " << oss.exceptions()   << "\n\n";

        cout << "executing:  oss.exceptions(ios::failbit);"             << "\n";
        oss.exceptions(ios::failbit);
        cout << "            oss.rdstate()    = " << oss.rdstate()      << "\n";
        cout << "            oss.exceptions() = " << oss.exceptions()   << "\n";
    }
    catch(const exception& x)
    {
        cout << endl;
        cout << "**** EXCEPTION THROWN ****"                            << "\n";
        cout << argv[0] << ":  " << x.what() << endl;
        cout << "            oss.rdstate()    = " << oss.rdstate()      << "\n";
        cout << "            oss.exceptions() = " << oss.exceptions()   << "\n";
        return 1;
    }
    catch(...)
    {
        cerr << argv[0] << ":  unknown exception." << endl;
        return 1;
    }
    return 0;
}

And here's the output: 这是输出:

matt@dworkin:~/dev/ostream/libs/ostream$ g++ --version
g++ (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

matt@dworkin:~/dev/ostream/libs/ostream$ g++ --std=c++17 foo.cpp
matt@dworkin:~/dev/ostream/libs/ostream$ ./a.out

            badbit           = 1
            eofbit           = 2
            failbit          = 4

            oss.rdstate()    = 0
            oss.exceptions() = 0

executing:  oss.setstate(ios::badbit | ios::failbit);
            oss.rdstate()    = 5
            oss.exceptions() = 0

executing:  oss.exceptions(ios::failbit);

**** EXCEPTION THROWN ****
./a.out:  basic_ios::clear: iostream error
            oss.rdstate()    = 5
            oss.exceptions() = 4

So based on the cplusplus.com docs, I wasn't expecting an exception to be thrown at all. 因此,基于cplusplus.com文档,我根本没想到会引发异常。 And as can be seen from the output generated from within the exception handler, no state flags were ever cleared. 从异常处理程序中生成的输出可以看出,从未清除任何状态标志。 So is this a compiler bug, a documentation bug, or am I missing something? 那么,这是编译器错误,文档错误还是我缺少什么?

As an aside, I prefer the behavior exhibited over the behavior documented. 顺便说一句,与记录的行为相比,我更喜欢表现出的行为。 Seems sorta strange to me that a request to throw on errors would have the side-affect of erasing existing errors. 对我来说似乎有点奇怪,要求抛出错误会产生擦除现有错误的副作用。 I actually first implemented it the same way g++ apparently does (assuming this was the way it would surely work), and only then read the docs for this method. 实际上,我首先以与g ++显然相同的方式实现了它(假定这肯定会起作用),然后才阅读此方法的文档。

cplusplus.com is wrong. cplusplus.com错误。 They are correct that clear is called by exceptions , but it is not called to clear the state and the state is not cleared. 他们是正确的, exceptions会调用clear ,但是不会调用clear来清除状态,也不会清除状态。

In spite of the name, clear is used in the back end by iostreams, including setstate itself , to do the grunt work for a great deal of setting, not just clearing, of the stream's state. 尽管有名称,但iostream( 包括setstate本身)在后端使用clear来完成繁琐的工作,以进行大量的设置,而不仅仅是清除流的状态。 As such, it is the logical place to house the raising of exceptions and other flag-related behaviours. 因此,这里是容纳例外情况和其他与国旗有关的行为的场所。

In exceptions it appears clear is being used primarily test for existing flags to raise an exception should any of the desired flags already be set. exceptionsclear已经被主要用于测试现有标志是否引发异常(如果已经设置了任何所需的标志)。 To actually clear the flags after the exception, a call to clear is still required to remove the error flags. 要在异常后真正清除标志,仍然需要调用clear来删除错误标志。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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