这是正确的行为吗?

时间:2019-02-14 20:59:31

标签: c++ exception

class foo {
    std::vector<int> datas;
public:
    template <typename It>
    foo(It x, It y) {
        for(; x != y; ++x)
            insert(*x);
    }

    void insert(int val) {
        if(val == 5)
            throw 99;
        else
            datas.push_back(val);
    }

    void print() const {
        for(int x : datas)
            std::cout << x << " ";
    }
};

int main() {
    std::vector<int> v{1, 2, 3, 5, 6, 7};
    foo* f;
    try {
        f = new foo(std::begin(v), std::end(v));
    }catch(int const& x) {
    }
    f->print();
}

我想在这种情况下不会构造f;在foo构造函数的主体中不处理insert方法抛出的异常。 我在gcc 8.2.0上得到以下输出: 1 2 3 5 6 7

2 个答案:

答案 0 :(得分:4)

  

我想在这种情况下不会构造f;

在这种情况下,不会构造foo实例。

此外,f不会被分配给它,因此其值将保持不确定。

  

这是正确的行为吗?

通过不确定的指针间接访问对象具有不确定的行为。

答案 1 :(得分:0)

虽然已经讨论了不确定的性质,但我认为调查实际产生的结果并推测为什么会看到它可能很有趣。

尽管我没有证据,但我相信这是编译器优化和代码推理的有趣结果。我们看到输出是1 2 3 5 6 7,即使代码中有元素throw的{​​{1}}语句也是如此。怎么会这样?

在我看来,由于我们在5块之外有f->print(),所以编译器会认为try从未被初始化-因此构造函数从不会抛出。由于构造函数不会抛出异常,因此f永远不会成立!因此,分支被删除。这样我们就得到了结果。