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 anexception-specification
that does not allow the exception, then, — if theexception-specification
is adynamic-exception-specification
, the functionstd::unexpected()
is called (15.5.2), — otherwise, the functionstd::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
Thestd::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 thedynamic-exception-specification
does not allow then the following happens: If thedynamic-exception-specification
does not include the classstd::bad_- exception
(18.8.2) then the functionstd::terminate()
is called, otherwise the thrown exception is replaced by an implementation-defined object of the typestd::bad_exception
and the search for another handler will continue at the call of the function whosedynamic-exception-specification
was violated. Thus, adynamic-exception-specification
guarantees that only the listed exceptions will be thrown. If thedynamic-exception-specification
includes the typestd::bad_exception
then any exception not on the list may be replaced bystd::bad_exception
within the functionstd::unexpected()
.
精彩评论