LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1462|回复: 9

求助异常处理:怎么让gcc(g++) 捕获数学计算的异常?

[复制链接]
发表于 2005-4-16 14:01:20 | 显示全部楼层 |阅读模式
  我想编一个能在Windows和Linux下运行的数学计算程序,可是在编写异常时出现了问题。以下这个程序能在Visual C++6.0和Dev-c++(gcc的windows版本)上运行。Visual C++6.0可以捕获数学计算的异常,但Dev-c++却没能抓上一个。

c++程序:
Little Change From microsoft Company MSDN

[php]
// Floating-point exception class sample
// Compile Options /GX
/*******************************************************************
    This program demonstrates how to use the exception classes
    from the diagnostics library to handle floating point exceptions;
    float_error class is derived from logic_error base class.
********************************************************************/
//#include <exception>
#include <stdexcept>
#include <cmath>
#include <iostream>
#include <complex>
using namespace std;
   //floating-point exception class
class float_error : public logic_error   
{
      public:
         float_error (char buffer[]) : logic_error (buffer)
         {
         cout <<"Floating point math error occurred in your program ";
         cout <<"More details below:"<<endl;
         }
   };
   //Math error handler
   int _matherr (struct _exception * ex)
   {
      char buffer [128];
      const char * ErrorType;

   //Determine type of error.
   cout<<"Ex type is: "<<ex->type<<endl;
      switch (ex->type)
         {
         case _DOMAIN:
             ErrorType = "Domain Error: ";
               break;
         case _SING:
            ErrorType = "Singularity Error:";
            break;
         case _OVERFLOW:
            ErrorType = "Overflow Error:";
            break;
         case _UNDERFLOW:
            ErrorType = "Underflow Error:";
            break;
         case _PLOSS:
            ErrorType = "artial Loss of significance:";
            break;
         case _TLOSS:
            ErrorType = "Total loss of significance:";
            break;
         default:
            ErrorType = "Some other math error:";
      }
   //Construct error string.
      sprintf (buffer, "%s: %s(%g,%g) returns %g",ErrorType,
             ex->name,ex->arg1,ex->arg2,ex->retval);
   //Throw an exception.
      
      throw float_error(buffer);
      return 0;
   }   
   void  TestMathErrors(double (*fp) (double), double arg)
   {
      //Next text
      bool caught = false;
      //Generate a floating-point error.
      try {
         double x = fp (arg);
         cout<<"x is: "<<x<<endl;
         }
      catch (exception & ex)
      {
         cout << ex.what() << endl<<endl;
         caught = true;
      }
      if (!caught)
         cout << "didn't catch exception through materr\r\n";
   }
   int main ()
   {
      typedef double (*fp) (double);
      //Array to the several functions
      fp math_function [] = { &sqrt, &log, &sin, &tan, &acos };  
      double arg []= { -1.0, 0.0, 1.5e25, 1.5e25, 2  };

      for (int n=0;  n < 5;n++)         
         TestMathErrors(math_function[n],arg[n]);

      system("AUSE");
      return 0;
   }
[/php]
 楼主| 发表于 2005-4-16 14:02:56 | 显示全部楼层

运行结果

Visual C++6.0的运行结果是:
Ex type is: 1
Floating point math error occurred in your program More details below:
Domain Error: : sqrt(-1,1.97024e-307) returns -1.#IND

Ex type is: 2
Floating point math error occurred in your program More details below:
Singularity Error:: log(0,1.97024e-307) returns -1.#INF

x is: -0.998843
didn't catch exception through materr
x is: -20.7731
didn't catch exception through materr
Ex type is: 1
Floating point math error occurred in your program More details below:
Domain Error: : acos(2,2.12719e-317) returns -1.#IND

而Dev-c++的运行结果是:

x is: -1.#IND
didn't catch exception through materr
x is: -1.#INF
didn't catch exception through materr
x is: -0.998843
didn't catch exception through materr
x is: -20.7731
didn't catch exception through materr
x is: -1.#IND
didn't catch exception through materr

请大侠们帮我分析一下到底是怎么回事吧。多谢了!
回复 支持 反对

使用道具 举报

发表于 2005-4-17 02:27:41 | 显示全部楼层
没有缩进,看的头晕
回复 支持 反对

使用道具 举报

发表于 2005-4-17 17:48:46 | 显示全部楼层
你可以看一下gcc 的编译选项中是否包含了 -fno-exceptions, 如果有你去掉它试试。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-4-17 21:01:41 | 显示全部楼层
Post by ryth
没有缩进,看的头晕


谢谢你的提醒!我刚学会了把它转成代码格式。请再帮我看看吧。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-4-17 21:12:43 | 显示全部楼层
Post by powerzhx
你可以看一下gcc 的编译选项中是否包含了 -fno-exceptions, 如果有你去掉它试试。


  谢谢powerzhx的回答!我是在Dev-c++下选择了"Enable exception handling "。在命令行(Dos)下用"g++ mathexc.cpp -o mathexc -lm"。这两种方式都不能捕获一个数学异常!很奇怪!
回复 支持 反对

使用道具 举报

发表于 2005-4-17 22:26:08 | 显示全部楼层
catch (exception & ex) 一句应改为catch (float_error & ex) 吧,因为你是throw oat_error类型的异常。
另外你可以在
      catch (float_error & ex)
      {
         cout << ex.what() << endl<<endl;
         caught = true;
      }
后添加
catch(...)
{
}
程序段捕获所有的异常试一下。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-4-17 22:36:00 | 显示全部楼层
Post by powerzhx
catch (exception & ex) 一句应改为catch (float_error & ex) 吧,因为你是throw oat_error类型的异常。
另外你可以在
      catch (float_error & ex)
      {
         cout << ex.what() << endl<<endl;
         caught = true;
      }
后添加
catch(...)
{
}
程序段捕获所有的异常试一下。


powerzhx兄弟, 你的方法我刚试了。可是和我以前的方法的结果一样啊。请帮我再看看吧。我是刚学异常处理的菜鸟了,多谢了!
回复 支持 反对

使用道具 举报

发表于 2005-4-17 22:59:43 | 显示全部楼层
#include <exception> 和#include <stdexcept>在Dev-c++里和vc里不知道是否一样,你可以看看库里定义是不是一样
void  TestMathErrors(double (*fp) (double), double arg)
   TestMathErrors(math_function[n],arg[n]); 不匹配吧?
 typedef double (*fp) (double) 这么定义好吗?
在Dev-c++里struct _exception 我没找到,但是有class  _exception 编译还能通过,不清楚

vc没看过不清楚
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-4-21 11:13:31 | 显示全部楼层
Post by ryth
#include <exception> 和#include <stdexcept>在Dev-c++里和vc里不知道是否一样,你可以看看库里定义是不是一样
void  TestMathErrors(double (*fp) (double), double arg)
   TestMathErrors(math_function[n],arg[n]); 不匹配吧?
 typedef double (*fp) (double) 这么定义好吗?
在Dev-c++里struct _exception 我没找到,但是有class  _exception 编译还能通过,不清楚

vc没看过不清楚


  ryth兄弟,你的直觉很好!#include <exception> 和#include <stdexcept>在Dev-c++里和vc里的确是不一样的。
  double (*fp) (double)是指向函数的指针。math_function [] 是函数名组成的数组,这样计算很方便的。 
  typedef double (*fp) (double) 是为了简化复杂的函数指针的表达,给输入和输出类型 都为double型的函数指针起了个简单的名字:fp。

  另外,struct _exception是在"math.h"里的。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表