Mutating Algorithm
Mutating Algorithm

Reputation: 2758

How to exit program execution after catching exception

I was looking at the answer to this question: Program doesn't stop after exception

The accepted writer proposes various techniques to exit a program upon catching an exception but also notes that

exit and abort will NOT call the destructors of your local objects.

So,if I use the first suggestion, which is to use the return keyword, how do I know what to return?

For example, I am writing a Stack<T> class and have implemented the Pop function like this:

template <typename T>
T Stack<T>::Pop() {

    try {

        return m_stack[--m_current_index];

    } catch(OutOfBoundsException &obe) {

        std::cout << "Stack Underflow" << std::endl;
    }

}

Here, m_stack is a custom array object of type Array<T> which throws an OutOfBoundsException.

Stack<T> follows a very basic implementation strategy where m_current_index represents the top of the Stack and the Stack size is fixed. So any push and pop operations simply increment or decrements m_current_index.

Suppose that my stack is instantiated as Stack<int> int_stack; and I have popped off all values on my Stack. Now when I call the Pop function (int_stack.Pop()) I get the following output.

Stack Underflow
5

5 is the value that is at index 0 of the array.

Now, if I use the return keyword to exit the program upon catching the exception, I can't really just return an integer because the user might think it's a valid value on the integer stack despite getting an exception.

Upvotes: 1

Views: 1434

Answers (1)

R Sahu
R Sahu

Reputation: 206717

So,if I use the first suggestion, which is to use the return keyword, how do I know what to return?

There are two issues here.

  1. Is it appropriate to return anything at all?
  2. What is an appropriate value to return?

If the answer to the first question is "Yes", then the second question is relevant. If the anwer to the first question is "No", then the second question is not relevant.

In your case, I would argue that the answer to the first question is "No". If you want the local objects' destructors to be called, your best option is to throw the exception back after the std::cout line.

template <typename T>
T Stack<T>::Pop() {

    try {

        return m_stack[--m_current_index];

    } catch(OutOfBoundsException &obe) {

        std::cout << "Stack Underflow" << std::endl;
        throw; // Throw the same exception
    }
}

Upvotes: 3

Related Questions