Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ -- Why 'what' print "Unknown exception" in catch scope?

Tags:

c++

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

like image 882
q0987 Avatar asked Jan 20 '23 00:01

q0987


2 Answers

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
}
like image 185
André Caron Avatar answered Jan 21 '23 13:01

André Caron


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.

like image 27
Fred Larson Avatar answered Jan 21 '23 15:01

Fred Larson