why does it cause termination if I try to throw something inside a catch block in C++
Asked Answered
C

2

11

I have the following C++ code and it gives me a surprise. The problem is that if I throw something except re-throw inside the catch block, the program will be terminated by calling abort and give the error message in GCC4, "terminate called after throwing an instance of 'int'". If I just use "throw;" to re-throw inside the catch block, everything will be fine.

#include <iostream> 
#include <exception>
#include <stdexcept>

using namespace std;

int main()
{
    try{
        throw std::string("first throw");
    }
    catch(std::string &x){
        try{
            std::cout << x << std::endl;
//          throw;  // if I use this line, all is fine.
            throw int(2); // but if I use this line, it causes Abort() to be called
        }
        catch (int &k){
            throw;
        }
        catch(...)
        {
            cout << "all handled here!"<< endl;
        }
    }
    catch(...){
        std::cout<< "never printed" << endl;
    }
}
Confiscate answered 23/1, 2012 at 16:43 Comment(1)
If you throw from a catch this is to be expected.Renaud
M
13

If you throw an int, then it won't be handled; it will be caught by the inner catch (int &k) handler, which rethrows it; and there is no outer handler to catch the rethrown exception, since you're already in an outer catch block. So in this case, terminate is called due to an unhandled exception.

If you rethrow the string, then it's caught by the inner catch(...) handler; this doesn't rethrow, so the exception has then been handled.

Malt answered 23/1, 2012 at 16:49 Comment(3)
Thanks, Mike. I think your answer is concise and right to the point.Confiscate
Is it common/recommended practice to throw string ?Footwear
@StephaneRolland: Usually, no; for reporting errors or other conditions that can't be handled locally, throw a custom type, usually a subclass of std::exception; and for other purposes you probably don't want to use exceptions in the first place. But for learning how exceptions work, string and int are as good as anything.Malt
H
7

You throw is not inside any try handler thus it leads to abort being called.

Here is your code with the indentation cleaned up a bit and some comments inline:

#include <iostream> 
#include <exception>
#include <stdexcept>

using namespace std;

int main()
{
    try {
        throw std::string("first throw");
    }
    catch (std::string &x) {
        try {
            std::cout << x << std::endl;
            // throw;  // if I use this line, all is fine.
            throw int(2); // but if I use this line, it causes Abort() to be called
        }
        catch (int &k) {
            // Catches and rethrows exception. Not inside a try thus leads to abort.
            throw;
        }
        catch (...) {
            // Will handle the case where the string is rethrown instead. No abort.
            cout << "all handled here!"<< endl;
        }
    }
    catch (...) {
        std::cout<< "never printed" << endl;
    }
}
Hemoglobin answered 23/1, 2012 at 16:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.