异常处理(限制异常)

时间:2011-07-31 19:24:03

标签: c++ exception-handling

我正在处理以下代码,&感到困惑,请看看它

#include<iostream>
#include<conio.h>
#include<string.h>

using namespace std;

void Xhandler(int test) throw(char,double)  /*i am restricting an integer exception     here by not including it in the argument list of throw*/
{
if(test==0) throw test;
if(test==1) throw 'a';
if(test==2) throw 123.23;
}

int main()
{
cout<"start";

try{
    Xhandler(0);  
}

catch(int i)  /*this catch statement must be ignored then,but it is running*/
{
    cout<<"caught an integer"; /*this is the output on the screen*/
}
catch(char c)
{
    cout<<"caught character";
}
catch(double a)
{
    cout<<"caught double";
}

cout<<"end";
    _getch();
    return 0;

     }

必须忽略对应于int的catch语句(不会被忽略)&amp;程序必须要终止,因为没有匹配的catch语句,但事实并非如此?

4 个答案:

答案 0 :(得分:2)

您没有指定编译器。如果您使用的是Microsoft Visual C ++,则MSDN上的Exception Specifications page会有一条注释

  

Visual C ++在其异常规范的实现中脱离了ANSI标准。下表总结了异常规范的Visual C ++实现:

     

...

     

throw(type) - 该函数可以抛出类型类型的异常。但是,在Visual C ++ .NET中,这被解释为throw(...)。

使用g ++时,运行示例时会因意外异常而终止进程。

答案 1 :(得分:2)

嗯,原因

catch(int i)  /*this catch statement must be ignored then,but it is running*/
{
    cout<<"caught an integer"; /*this is the output on the screen*/
}

异常处理程序被执行而不是被调用的意外处理程序可能与您的编译器有关。

具有异常规范的函数抛出异常但标准异常的类型与异常规范不匹配时的标准符合行为将是调用意外处理程序。默认处理程序终止程序。

实际上,许多编译器会忽略异常规范,有些可能会发出一些警告告诉您。编译器忽略它们是个好主意。

C ++中的异常规范不能按照您希望的方式工作。异常规范并不意味着编译器保证除了异常规范中提到的异常之外,该函数不会抛出任何其他异常。在标准的一致编译器中,它只是意味着编译器必须在运行时强制执行异常规范(如果抛出的异常与异常规范匹配,那么你很好,如果不是,你最终应该在意外的处理程序中)

有关异常规范的更多信息以及为什么要避免它们,请参阅here(Herb Sutter解释说,C ++中的异常规范主要不是它们应该是/大多数人认为的那样)。您可以在页面底部获得更多链接...

答案 2 :(得分:0)

您的Xhandler例程在声明不会抛出int个例外后抛出int例外。这是未定义的,所以任何事情都可能发生。

答案 3 :(得分:0)

此行为的原因如下: 如果抛出的异常在type指定的异常类型列表中不匹配,则调用std::unexpected()。哪个进一步根据异常类型列表中是否包含std::bad_exception来引发相应的异常类型

以下内容摘自C ++ 11标准草案(文件号:N3337):(虽然草案标准不是最终标准,但它符合此目的)

  

15.4例外规范[9]
  每当抛出异常并且搜索处理程序(15.3)遇到具有exception-specification且不允许异常的函数的最外层块时,则,    - 如果exception-specificationdynamic-exception-specification,则调用函数std::unexpected()(15.5.2),    - 否则,调用函数std::terminate()(15.5.1)。

     

[ Example: void f() throw (X, Y) { int n = 0; if (n) throw X(); // OK if (n) throw Z(); // also OK throw W(); // will call std::unexpected() } —end example ]

以下摘录定义了std::unexpected()函数的行为:

  

15.5.2 std::unexpected()功能
  std::unexpected()函数不会返回,但它可以抛出(或重新抛出)异常。如果它抛出了先前违反的异常规范所允许的新异常,则在调用违反异常规范的函数时将继续搜索另一个处理程序。如果它抛出或重新抛出dynamic-exception-specification不允许的异常,则会发生以下情况:如果dynamic-exception-specification不包含类std::bad_- exception(18.8.2),则函数{{1调用,否则抛出的异常被类型为std::terminate()的实现定义的对象替换,并且在调用违反std::bad_exception的函数时将继续搜索另一个处理程序。因此,dynamic-exception-specification保证只抛出列出的异常。如果dynamic-exception-specification包含dynamic-exception-specification类型,则列表中未列出的任何异常都可能会被std::bad_exception函数中的std::bad_exception替换。