CPP Exception Handling & Error Management 2 — Questions and Answers
Question 1: What happens when an exception is thrown inside a destructor that is already executing due to stack unwinding?
- The new exception replaces the original exception
- std::terminate() is called (Correct answer)
- The destructor exception is silently ignored
- The program enters an undefined state but continues
Correct answer: std::terminate() is called
If a destructor throws while another exception is being propagated (stack unwinding), std::terminate() is called because two exceptions cannot be active simultaneously.
Question 2: Which of the following correctly creates a custom exception class that follows best practices?
- class MyEx { string msg; };
- class MyEx : public std::exception { public: const char* what() const noexcept override { return "error"; } }; (Correct answer)
- class MyEx : public std::exception { public: const char* what() { return "error"; } };
- class MyEx : private std::exception { };
Correct answer: class MyEx : public std::exception { public: const char* what() const noexcept override { return "error"; } };
Best practice is to inherit publicly from std::exception and override what() as const noexcept to match the base class contract.
Question 3: What does the noexcept specifier guarantee when applied to a function?
- The function cannot be called if exceptions are active
- The compiler optimizes the function assuming no exceptions will propagate out (Correct answer)
- The function will catch and suppress any thrown exceptions
- The function return type must be void
Correct answer: The compiler optimizes the function assuming no exceptions will propagate out
noexcept tells the compiler no exceptions will propagate out, enabling optimizations; if one does, std::terminate() is called.
Question 4: What is the output of: try { throw 42; } catch (double d) { cout << "double"; } catch (...) { cout << "other"; }
- double
- other (Correct answer)
- 42
- Compile error
Correct answer: other
An int literal 42 does not match catch(double), so the catch-all handler catch(...) executes.
Question 5: Which function can be used to rethrow the currently active exception inside a catch block?
- throw new;
- rethrow();
- throw; (Correct answer)
- throw std::current_exception();
Correct answer: throw;
A bare throw; statement inside a catch block rethrows the currently active exception preserving its original type.
Question 6: What is std::exception_ptr used for?
- Pointing to the base class of an exception hierarchy
- Storing and transporting exceptions across threads (Correct answer)
- Creating polymorphic exception objects
- Deleting caught exception objects
Correct answer: Storing and transporting exceptions across threads
std::exception_ptr captures an exception with std::current_exception() and allows rethrowing it later, even in a different thread.
Question 7: In a catch clause, what is the advantage of catching by reference (catch(std::exception& e)) over catching by value?
- References allow modifying the original exception object
- It prevents object slicing when catching derived exceptions through a base reference (Correct answer)
- References are required; catching by value is a compile error
- It avoids calling the copy constructor and is always faster
Correct answer: It prevents object slicing when catching derived exceptions through a base reference
Catching by reference prevents slicing, ensuring the derived type's what() and virtual methods are called correctly.
What happens when an exception is thrown inside a destructor that is already executing due to stack unwinding?