为什么>>运算符在不同的编译器上显示不同的结果?

Ris*_*rma 2 c++ istream

我的代码在不同的IDE上显示了不同的结果。对于1//2我的IDE上的输入,它显示输入格式错误,但是在其他IDE上,它引发DivisionByZero

我尝试过包括in.peek() == '/' 这样做,尽管这样做没有道理,但无济于事。

struct DivisionByZero : public exception {
    const char * what() const throw() {
        return "Zero Denominator";
    }
};
Run Code Online (Sandbox Code Playgroud)

R的构造函数

R::R(int n, int d)
{
    if (d==0)
    {
        throw DivisionByZero();
    }
    n_ = n * (d / abs(d));
    d_ = abs(d);
}
Run Code Online (Sandbox Code Playgroud)

操作员>>

std::istream &operator>>(std::istream &in, R &r){
    int n, d;
    in >> n;

    if (in.peek() == '/')
    {
        in.ignore();
        if ( (in.peek() < '0' || in.peek() > '9') ){
            in.setstate(ios_base::failbit);
        }
        in >> d;
        r = R(n, d);
    }
    return in;
}
Run Code Online (Sandbox Code Playgroud)

main()代码

R n1, n2;
char op;
try
{
while (cin >> n1 >> op >> n2) {
    switch (op) {
        case '+':
            cout << n1 + n2 << endl;
            break;
        case '-':
            cout << n1 - n2 << endl;
            break;
        case '*':
            cout << n1 * n2 << endl;
            break;
        case '/':
            cout << n1 / n2 << endl;
            break;
        }
    }
}
catch(DivisionByZero& e){
    cerr << e.what();
    return 1;
}
if (cin.fail())
{
    cin.clear();
    cerr << "Input format error before '" << char(cin.peek()) <<"'";
    return 2;
}
return 0;
Run Code Online (Sandbox Code Playgroud)

预期产量Input format error before '/'

实际输出Zero Denominator

Igo*_*nik 6

in >> d失败,因为流中的字符无法解析为整数。d仍未初始化。R(n, d)然后d,通过访问未初始化的对象,无论做什么都表现出未定义的行为。

  • 在提取失败时,`istream`s将从C ++ 11开始将其值清零。该变量不再保留不变。如果要针对比C ++ 11早的C ++版本进行编译,这只是未定义的行为。 (6认同)
  • @FrançoisAndrieux我不认为流从一开始就设置了“ failbit”。OP的代码在尝试提取之前显式设置了“ failbit”。 (2认同)
  • @FrançoisAndrieux在标准的实际文本中,将val设置为零是由[`num_get :: do_get`]完成的(http://eel.is/c++draft/facet.num.get.virtuals#3.3 .6),而不是由`operator &gt;&gt;`本身。但是,如果已经设置了“失败位”,则[哨兵对象](http://eel.is/c++draft/istream.formatted.reqmts#1)会注意到和[`operator &gt;&gt;`](http ://eel.is/c++draft/istream.formatted.arithmetic#1)无法到达“ num_get”调用。 (2认同)