因此,我在编写一些代码时注意到,除了语法、类型和其他编译时错误之外,C++不会抛出任何其他异常。所以我决定用一个非常简单的程序来测试一下:
#include<iostream>
int main() {
std::count<<5/0<<std::endl;
return 1
}
当我使用g++编译它时,g++给了我一个警告,说我正在被0除。但它仍然编译了代码。然后当我运行它的时候,它打印了一些非常大的任意数字。当我想知道的时候,C++是如何处理异常的?整数除以0应该是一个非常简单的例子,说明何时应该抛出异常,程序应该终止。
实际上,我是否必须将整个程序封装在一个巨大的try块中,然后捕获某些异常?我知道在Python中,当抛出异常时,程序会立即终止并打印出错误。C++是做什么的?是否存在停止执行并杀死程序的运行时异常?
发布于 2012-06-07 04:35:44
有运行时异常,但并不是所有“错误”的东西都会导致抛出运行时异常。例如,访问超出边界的数组或取消引用空指针是简单的“未定义行为”-这意味着任何事情都可能发生。除以零也属于“未定义”的范畴。
导致“未定义行为”而不是异常的一些操作的基本原理是效率。假设越界数组访问需要抛出异常。然后,编译器必须为每个数组访问生成代码,以检查它是否越界,如果越界,则抛出异常。这是大量的检查,其中大部分是不必要的。相反,编译器所做的只是生成用于元素访问的指令,假设它在范围内。如果它碰巧超出了边界,那么无论发生什么(例如分段错误)都会发生。如果你想要一个检查被执行,你总是可以显式地编码它。
这使得C++比通常执行检查的语言(例如Java或python)更强大,因为您可以选择何时进行检查,以及何时不进行检查。(另一方面,它使C++不如Java或python安全。这是一种权衡)。
至于当抛出异常但没有在任何地方捕获时会发生什么,通常编译器实现将打印包含异常的what()
的错误消息。在您的示例中,这是不适用的,因为没有抛出运行时异常。
发布于 2012-06-07 04:33:14
是的,存在运行时异常。vector::at
抛出的out_of_range
就是一个例子。
但是,除零是未定义的(C++0x§5.6/4):
如果/或%的第二个操作数为零,则行为在fined下。
因此它可能无法编译、抛出一个虚构异常、打印“一些非常大的任意数”或segfault。
发布于 2012-06-07 04:36:32
C++只抛出在C++标准中定义良好的标准异常(是的,它包含一些运行时异常)。
整数除以零不是标准的行为异常(从技术上讲,它是未定义的行为)。所以不会抛出任何隐式异常。一个特定的编译器可能会将运行时错误映射到某种类型的异常(您需要查看编译器文档来了解这一点,一些编译器将除以零映射到某个异常),如果是这样的话,您就可以捕获该特定的异常。但是,请注意,这不是可移植的行为,并且不适用于所有编译器。
最好的做法是自己检查错误条件(除数等于零),并在这种情况下显式抛出异常。
EDIT:回复评论的
class A
{
public:
void f()
{
int x;
//For illustration only
int a = 0;
if(a == 0)
throw std::runtime_error( "Divide by zero Exception");
x=1/a;
}
A()
{
try
{
f();
}
catch(const std::runtime_error& e)
{
cout << "Exception caught\n";
cout << e.what();
}
}
};
https://stackoverflow.com/questions/10925675
复制相似问题