C++异常处理

C++ Exception Handling

本文关键字:异常处理 C++      更新时间:2023-10-16

所以我正在编写一些代码,我注意到除了语法、类型和其他编译时错误之外,C++ 没有抛出任何其他异常。所以我决定用一个非常简单的程序来测试它:

#include<iostream>
int main() {
    std::count<<5/0<<std::endl;
return 1
}

当我使用 g++ 编译它时,g++ 给了我一个警告,说我被 0 除以。但它仍然编译了代码。然后当我运行它时,它打印了一些非常大的任意数字。当我想知道是,C++如何处理异常?整数除以 0 应该是一个非常微不足道的示例,说明何时应该抛出异常并且程序应该终止。

我是否必须基本上将我的整个程序包含在一个巨大的 try 块中,然后捕获某些异常?我知道在 Python 中当抛出异常时,程序将立即终止并打印出错误。C++做什么?是否有停止执行并杀死程序的运行时异常?

存在运行时异常,但并非所有"错误"都会导致引发运行时异常。例如,越界地接收数组或取消引用空指针只是"未定义的行为"——这意味着任何事情都可能发生。除以零也属于"未定义"类别。

某些操作导致"未定义的行为"而不是例外的理由是效率。假设越界数组访问需要引发异常。然后,编译器必须为每个数组访问生成代码,以检查它是否越界,如果是,则引发异常。这是很多检查,其中大部分是不必要的。相反,编译器所做的只是为元素访问生成指令,假设它在边界内。如果它碰巧超出界限,那么无论发生什么(例如分段错误)都会发生。如果要执行检查,则始终可以显式编码。

这使得C++比总是执行检查的语言(例如Java或Python)更强大,因为您可以选择何时完成检查,何时不进行检查。(另一方面,它使C++不如Java或python安全。这是一种权衡)。


至于当抛出异常但没有在任何地方捕获时会发生什么,通常编译器实现会打印包含异常what()的错误消息。在您的示例中,这不适用,因为没有引发运行时异常。

是的,存在运行时异常。 一个例子是out_of_range,它由vector::at抛出。

但是,除以零是未定义的 (C++0x §5.6/4):

如果/或 % 的第二个操作数为零,则行为未定义。

因此,它可能无法编译,抛出一个虚构的异常,打印"一些非常大的任意数字",或者段错误。

C++仅抛出在C++标准中明确定义的标准异常。是的,它包括一些运行时异常

整数除以零不是标准的C++例外(从技术上讲,它是未定义的行为)。因此,不会引发隐式异常。特定的编译器可能会将运行时错误映射到某种异常(您需要检查编译器文档,某些编译器将除以零映射到某个异常),如果是这样,您可以捕获该特定异常。但是,请注意,这不是可移植行为,并且不适用于所有编译器。

您能做的最好的事情是自己检查错误条件(除数等于零),并在这种情况下显式抛出异常。

编辑:回答评论

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 caughtn";
                   cout << e.what(); 
              }
         }
 };     

Visual C++正确地将其标记为除以零错误。因此,如果它不编译,那么就没有运行它的问题。