在 C++ 中有可能什么都不抛出吗?

Is is possible in C++ to throw nothing?

在异常情况下,我希望我的程序停止处理,向std::cerr输出错误,清理并退出。

但是,调用exit()不会调用任何已构造对象的所有析构函数。我想让析构函数调用得很好,所以我将所有代码包装在一个 try-catch 块中,如下所示:

int main(int argc, char** argv){
    try {
        bool something_is_not_right = false;
        /* lots of variables declared here */
        /* some code that might set something_is_not_right to true goes here */
        if(something_is_not_right){
            std::cerr << "something is not right!!!" << std::endl;
            throw '[=10=]';  // dummy unused variable for throwing.
        }
    }
    catch (...) {}
    return 0;
}

通过这种方式,我可以保证销毁所有变量。但我似乎找不到让 C++ 达到 throw 的方法。 throw;在C++中有特殊含义;它什么也没扔。

有没有办法throw什么都没有?

好吧,你 "can" 但它并没有抛出任何东西。它终止了。

5.17 Throwing an exception:

  1. Evaluating a throw-expression with an operand throws an exception (15.1)
  2. A throw-expression with no operand rethrows the currently handled exception (15.3).
  3. If no exception is presently being handled, evaluating a throw-expression with no operand calls std::terminate()

这是有效的:

int main () {
  throw;
  return 0;
}

使用的来源:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf

但它不会清除任何东西。 std::terminate 在清理失败时使用。

否则你必须使用操作数,然后这部分变得相关:

15.1 Throwing an exception [except.throw]

  1. Throwing an exception copy-initializes (8.5, 12.8) a temporary object, called the exception object. The temporary is an lvalue and is used to initialize the variable declared in the matching handler (15.3).

所以你必须传递一些能够被初始化的东西,根据定义不能什么都没有。

你怎么知道捕获的原因是你的错误还是其他原因(内存不足总是好的)。如果您检测到错误,那么您应该在自定义异常中创建并抛出该错误的原因。然后总的来说,您可以区分检测到的错误和未预料到的错误。这只是个好习惯。

没有

不可能什么都不扔。你需要扔东西。虽然您可能已经看到人们使用 throw 关键字但没有任何内容,这仅意味着他们正在重新抛出当前处理的异常。

这不是对您问题的直接回答,而是个人推荐。

您可能想查看 stdexcept which cover almost any exceptional behaviour that occurs in a program. In your case I would throw a std::runtime_error. Also, only catch what you expect to be thrown and not catch 'em all. If you really want to catch everything, then catch std::exception 的预定义异常(所有标准异常的基础 class)。

在我看来,处理未知异常没有任何意义,唯一合乎逻辑的结果就是中止执行。

#include <iostream>
#include <stdexcept>

int main()
{
  try
  {
    bool something_is_not_right = true;
    if ( something_is_not_right )
      throw std::runtime_error("something is not right!!!");
  }
  catch (std::runtime_error& e)
  {
    std::cerr << e.what() << '\n';
    throw;
  }
}

为了确保完全清理,您必须抛出异常并在某处捕获它。当异常被抛出但未被捕获时,实现不需要清理堆栈对象。要求(在[except.handle]/9)抛出异常但未捕获异常是程序调用std::terminate(),是否清除堆栈对象是实现定义的。