Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

A throw expression is a control-flow construct used to raise an exception, transferring program execution to the nearest dynamically enclosing exception handler (catch block). It signals an anomalous runtime condition by initializing an exception object and initiating the stack unwinding process.

Syntax

The throw expression has two distinct syntactic forms:
throw expression; // Form 1: Throws a new exception object
throw;            // Form 2: Rethrows the currently handled exception

Type and Value Category

The throw expression itself is a prvalue of type void. Because its type is void, it cannot be used in contexts that require a value, but it can be used as the second or third operand in a conditional ternary operator (?:).

Mechanics of throw expression;

When a throw expression with an operand is evaluated, the C++ runtime performs the following sequence of operations:
  1. Operand Evaluation: The expression is evaluated.
  2. Type Determination: The type of the exception object is determined by the static type of the expression. Top-level const and volatile qualifiers are stripped. References are removed. Arrays and functions decay to corresponding pointers.
  3. Exception Object Allocation: The runtime allocates memory for the exception object in an unspecified, implementation-defined storage space (neither the standard call stack nor the standard heap).
  4. Initialization: The exception object is copy-initialized or move-initialized from the evaluated expression.
  5. Stack Unwinding: The runtime begins linearly exiting scopes from the throw point up to the matching catch clause. Destructors for all fully constructed automatic objects in these scopes are invoked in reverse order of their construction.
  6. Control Transfer: Execution resumes at the matched catch block.

Mechanics of the Rethrow Expression (throw;)

A throw expression without an operand is known as a rethrow.
  • Context: It is only valid when an exception is currently being handled (either lexically inside a catch block or dynamically inside a function invoked from within a catch block).
  • State Preservation: It resumes the propagation of the existing exception object. It does not evaluate a new expression or copy-initialize a new exception object.
  • Polymorphism: Because it reuses the existing exception object, it preserves the original dynamic type of the exception, preventing the object slicing that would occur if the exception were re-thrown by name (e.g., throw e;).
  • Termination: If throw; is executed when no exception is currently active, the runtime immediately invokes std::terminate().

Exception Safety and Edge Cases

  • Exceptions during initialization: If the copy or move constructor invoked during the initialization of the exception object throws an exception, the runtime immediately calls std::terminate().
  • Exceptions during operand evaluation: If the evaluation of the expression itself throws an exception before the throw expression is fully executed, the original throw is abandoned, and the new exception propagates instead.
  • Noexcept contexts: If a throw expression is evaluated inside a function marked noexcept (and the exception is not caught within that same function), the runtime invokes std::terminate() instead of unwinding the stack past the noexcept boundary.
Master C++ with Deep Grasping Methodology!Learn More