在 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:
- Evaluating a throw-expression with an operand throws an exception (15.1)
- A throw-expression with no operand rethrows the currently handled exception (15.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]
- 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()
,是否清除堆栈对象是实现定义的。
在异常情况下,我希望我的程序停止处理,向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:
- Evaluating a throw-expression with an operand throws an exception (15.1)
- A throw-expression with no operand rethrows the currently handled exception (15.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]
- 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()
,是否清除堆栈对象是实现定义的。