开发者

exception handling(restricting exceptions)

i was dealing with the following code,& got confused,please have a look at it

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

using namespace std;

void Xhandler(int test) throw(char,double)  /*i am restricting an integer ex开发者_运维问答ception     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;

     }

the catch statement corresponding to int must be ignored(which is not ignored) & program must have to be terminated as there is no matching catch statement left,but it is not so?


You did not specified the compiler. If you are using Microsoft visual C++ there is a note at Exception Specifications page on the MSDN

Visual C++ departs from the ANSI Standard in its implementation of exception specifications. The following table summarizes the Visual C++ implementation of exception specifications:

...

throw(type) - The function can throw an exception of type type. However, in Visual C++ .NET, this is interpreted as throw(...).

When using g++ the process is terminated due unexpected exception when running your example.


Well, the reason the

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*/
}

exception handler gets executed instead of the unexpected handler being called lies probably with your compiler.

The standard conform behavior when an exception is thrown by a function with exception specification but the type of the thrown exception does not match the exception specification would be that the unexpected handler gets called. The default handler terminates the program.

In reality many compilers ignore exception specifications and some might just issue some warnings telling you that. That the compilers ignore them is a good idea imho.

An exception specification in C++ does not work the way you would like it to. An exception specification does not mean that the compiler guarantees that the function cannot throw any other exceptions besides the ones mentioned in the exception specification. In a standard conform compiler it just means that the compiler has to enforce the exception specification at runtime (if the exception being thrown matches the exception specification you are fine, if not you should end up in the unexpected handler)

For more info on exception specifications and why you should avoid them see here (Herb Sutter explains there mostly that exception specifications in C++ are not what they should be/most people think they are). And you get some further links at the bottom of the page...


Your Xhandler routine throws an int exception after declaring that it won't throw int exceptions. This is undefined, so anything might happen.


The reason of this behavior is as follow: If the thrown exception don't match in the type specified exception type-list then std::unexpected() is called. Which further throws the appropriate exception type based upon if std::bad_exception is included or not in exception type-list.

Following are excerpt from C++11 draft standard(Document Number: N3337):(Though draft standards are not final standard but it serves the purpose here)

15.4 Exception specifications[9]
Whenever an exception is thrown and the search for a handler (15.3) encounters the outermost block of a function with an exception-specification that does not allow the exception, then, — if the exception-specification is a dynamic-exception-specification, the function std::unexpected() is called (15.5.2), — otherwise, the function std::terminate() is called (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 ]

Following excerpt defined behavior of std::unexpected() function:

15.5.2 The std::unexpected() function
The std::unexpected() function shall not return, but it can throw (or re-throw) an exception. If it throws a new exception which is allowed by the exception specification which previously was violated, then the search for another handler will continue at the call of the function whose exception specification was violated. If it throws or rethrows an exception that the dynamic-exception-specification does not allow then the following happens: If the dynamic-exception-specification does not include the class std::bad_- exception (18.8.2) then the function std::terminate() is called, otherwise the thrown exception is replaced by an implementation-defined object of the type std::bad_exception and the search for another handler will continue at the call of the function whose dynamic-exception-specification was violated. Thus, a dynamic-exception-specification guarantees that only the listed exceptions will be thrown. If the dynamic-exception-specification includes the type std::bad_exception then any exception not on the list may be replaced by std::bad_exception within the function std::unexpected().

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜