【问题标题】:Why exceptions have to be thrown manually?为什么必须手动抛出异常?
【发布时间】:2013-04-19 14:27:26
【问题描述】:

我已经在 PHP 和 C++ 中尝试过,所以我的问题只针对它们。为什么我们必须自己throw异常并且在出现异常问题时它们不会自动抛出。

PHP 代码优先

<?php 
try{ 
$a=1;
$b=0;
echo $a/$b;
} catch (Exception $e) { 
    echo "Error : ".$e->getMessage();
} 
?> 

为什么这段代码不会抛出除以零异常?可以通过以下方式完成

<?php 
  try{ 
    $a=1;
    $b=0;
    if($b==0)
    {
          throw new Exception("What's the point in an exception if its not automatic and i have to throw it myself");
    }
    echo $a/$b;
    } catch (Exception $e) { 
        echo "Error : ".$e->getMessage();
    } 
?> 

但是异常处理的意义何在,如果我必须自己编写可能的异常代码,那么为什么不使用任何简单的错误报告模式呢?

以下同样适用

C++ 代码

int main()
{
try{ 
    int a=1;
    int b=0;
    cout<<(a/b);
  }
   catch (string e)
     {
         cout << e << endl;
     }
}

如果没有进行异常处理,这不会产生异常,会产生运行时错误并使应用程序崩溃。以下作品

int main()
{
try{ 
    int a=1;
    int b=0;
    if(b==0)
    {
     throw string("What's the point in an exception if its not automatic and i have to throw it myself");
    }
    cout<<(a/b);
  }
  catch (string e)
  {
     cout << e << endl;
  }
}

问题

为什么我必须手动检查这些变量才能发现错误?当我已经告诉代码这会发生时,异常真的是异常吗?那为什么优先于基本if条件

【问题讨论】:

标签: php c++ exception divide-by-zero


【解决方案1】:

至少对于 C++ 而言,原因是因为检查零除数然后抛出和处理 expetion 会严重影响某些系统的性能。因此,根据 C++ 标准,除以零是未定义的行为。

5.6 乘法运算符

4 二元 / 运算符产生商,二元 % 运算符产生除法的余数 第二个表达式的第一个表达式。如果 / 或 % 的第二个操作数为零,则行为未定义。为了 整数操作数 / 运算符产生代数商,丢弃任何小数部分;81 如果 商 a/b 可以用结果的类型来表示,(a/b)*b + a%b 等于 a;否则,行为 a/b 和 a%b 都是未定义的

有些实现会抛出异常。但是,如果使用不同的编译器编译代码,则可能会导致意想不到的结果。例如在 msvc 中查看 SEH

5 个表达式

4 如果在计算表达式期间,结果未在数学上定义或不在 其类型的可表示值,行为是未定义的。 [注意:大多数现有的 C++ 实现 忽略整数溢出。 除以零的处理,使用零除数形成余数,以及所有 浮点异常因机器而异,通常可以通过库函数进行调整。 —尾注]

【讨论】:

    【解决方案2】:
    <?php
    
    function exception_error_handler($errno, $errstr, $errfile, $errline ) {
        throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
    }
    set_error_handler("exception_error_handler");
    
    try{
        $a=1;
        $b=0;
        echo $a/$b;
    } catch (Exception $e) {
        echo "Error : ".$e->getMessage();
    }
    

    输出:

    Error : Division by zero
    

    【讨论】:

      【解决方案3】:

      无法与 PHP 对话,但在 C++ 中,代码被编译为带有 CPU 指令的本机代码。它没有进行任何高级处理,因此生成的异常对于这种原始操作没有意义。此外,这种类型的验证会减慢数学运算。异常的缺点是性能。

      很可能 PHP 的设计者也不想在简单的数学运算中检查输入错误对性能造成影响。

      【讨论】:

        【解决方案4】:

        在 POSIX 操作系统上的 C/C++ 中(出于所有实际目的,除 Windows 之外的所有应用程序),只要“执行了非法算术运算”(例如除以零),就会向应用程序发送信号 SIGFPE。会使用signal 系统调用为此安装处理程序。

        信号与异常不同,您不能只是从信号处理程序中抛出异常——信号处理程序在与其余代码不同的帧中执行。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-05-11
          • 1970-01-01
          • 2010-10-15
          • 1970-01-01
          • 1970-01-01
          • 2010-12-09
          • 1970-01-01
          • 2013-02-11
          相关资源
          最近更新 更多