为什么必须手动抛出异常?

时间:2013-04-19 14:27:27

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

我在PHP和C ++中尝试过这个,所以我的问题仅针对它们。为什么我们必须自己throw例外,并且在发生异常问题时不会自动抛出它们。

PHP Code First

<?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条件

4 个答案:

答案 0 :(得分:3)

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

5.6乘法运算符

  

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

某些实现通过抛出异常。但是,如果使用不同的编译器编译代码,那么转发可能会导致意外的结果。例如,请参阅msvc中的SEH

5表达式

  

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

答案 1 :(得分:1)

<?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

答案 2 :(得分:0)

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

PHP的设计者当然也不希望在简单的数学运算中检查输入错误的性能。

答案 3 :(得分:0)

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

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