Reputation: 6546
Consider this code:
int main()
{
try
{
throw std::range_error("");
}
catch (std::bad_alloc)
{
std::cout << "AAAA" << std::endl;
throw;
}
catch (std::range_error)
{
std::cout << "BBB" << std::endl;
throw;
}
catch (std::exception)
{
std::cout << "CCC" << std::endl;
}
std::cout << "DDD" << std::endl;
}
Here I throw an exception of type std::range_error
and trying to catch it.
Logically the first catch
block cannot catch it because of type mismatch(std::bad_alloc
and std::range_error
).
The second catch block must catch it because they are the same types of std::range_error
.
And also, when I rethrow the exception in second catch block it must be caught in the third catch block.
So my output must be
BBB
CCC
DDD
But I only get the BBB
output with the termination.
Can anybody please explain me the behavior??
Upvotes: 5
Views: 849
Reputation: 21576
When you re-throw
an exception, you are throwing it completely out of the context of the current exception handling block.... So,
try
{
throw std::range_error("");
}
catch (std::bad_alloc)
{
std::cout << "AAAA" << std::endl;
throw;
}
catch (std::range_error)
{
std::cout << "BBB" << std::endl;
throw;
}
catch (std::exception)
{
std::cout << "CCC" << std::endl;
}
is one exception handling block. Therefore, on meeting the first throw
in any of the catch
blocks, it leaves the whole block to look for another handling block (try-catch) outside the current scope. if not found, the program terminates.
Please see try-catch
block in C++
To print as you initially thought ... Live On Coliru ...
int main()
{
try{
try{
try{
throw std::range_error("");
}
catch (std::bad_alloc) {
std::cout << "AAAA" << std::endl;
throw;
}
}
catch (std::range_error) {
std::cout << "BBB" << std::endl;
throw;
}
}
catch (std::exception){
std::cout << "CCC" << std::endl;
}
std::cout << "DDD" << std::endl;
}
Prints:
BBB
CCC
DDD
For the record: please avoid using exceptions for control flow that could be done with simple if-else
ladder in production code
Upvotes: 6
Reputation: 3089
To re-catch the range_error and new outer try catch block is required.
#include <iostream>
int main()
{
//outer try catch ------------------------
try {
// inner try catch ---------------------
try
{
throw std::range_error("");
}
catch (std::bad_alloc)
{
std::cout << "AAAA" << std::endl;
throw;
}
catch (std::range_error)
{
std::cout << "BBB" << std::endl;
throw;
}
// -------------------------------
}
catch (std::exception)
{
std::cout << "CCC" << std::endl;
}
// --------------------------------
std::cout << "DDD" << std::endl;
}
Output
BBB
CCC
DDD
Upvotes: 5
Reputation: 302708
This throw
:
catch (std::range_error)
{
std::cout << "BBB" << std::endl;
throw; // <== this one
}
isn't itself within the body of a try
, so when the exception handling mechanism will keep going out one scope at a time until it finds one. Since there is no other outer try
, the exception isn't caught at all.
There is no reentrance in exception handling.
Upvotes: 4