C++ -- Why 'what' print "Unknown exception" in catch scope?
try
{
range_error r("Hi I am hereeeee!");
cout << r.what() << endl; // print "Hi I am hereeeee!" // case one
exception *p2 = &r;
开发者_开发知识库 cout << p2->what() << endl; // print "Hi I am hereeeee!" // case two
throw p2;
}
catch (exception *e)
{
cout << e->what() << endl; // print "Unknown exception" // case three
}
Question>
I don't know why case three prints "Unknown exception" instead of "Hi I am hereeeee!"? The printed result is copied from VS2010
This program results in undefined behavior. Because the variable r
is declared inside the try
block, it goes out of scope before the catch handler is invoked. At this point, e
points to some area on the stack where an object of type range_error
used to exist.
The following program should print the expected results:
range_error r("Hi I am hereeeee!");
try
{
cout << r.what() << endl; // print "Hi I am hereeeee!" // case one
exception *p2 = &r;
cout << p2->what() << endl; // print "Hi I am hereeeee!" // case two
throw p2;
}
catch (exception *e)
{
cout << e->what() << endl; // print "Hi I am hereeeee!" // case three
}
However, you should not throw a pointer to an object, you should throw the object itself. The run-time library will store a copy of the range_error
object and pass that copy to the exception handler.
Thus, you should use the following code instead:
try
{
range_error r("Hi I am hereeeee!");
cout << r.what() << endl; // print "Hi I am hereeeee!" // case one
throw r;
}
catch (const exception& e)
{
cout << e.what() << endl; // print "Hi I am hereeeee!" // case two
}
Because by the time you get to the catch
, your range_error
has been destroyed and you're catching a dangling pointer. Either move the range_error
declaration outside the try
block or, better yet, throw an instance and catch by reference.
Because the pointed to exception object has gone out of scope by the time you catch the exception. If you wrote
range_error r("Hi I am hereeeee!");
try
{
cout << r.what() << endl; // print "Hi I am hereeeee!" // case one
exception *p2 = &r;
cout << p2->what() << endl; // print "Hi I am hereeeee!" // case two
throw p2;
}
catch (exception *e)
{
cout << e->what() << endl; // print "Unknown exception" // case three
}
it would print what you expected.
精彩评论