Docs

README

Exception Handling in C++

Table of Contents

  1. Exception Basics
  2. try-catch Blocks
  3. Throwing Exceptions
  4. Standard Exceptions
  5. Custom Exceptions
  6. Exception Specifications
  7. Best Practices

Exception Basics

Exceptions provide error handling separate from normal code flow:

try {
    // Code that might throw
    throw runtime_error("Something went wrong");
}
catch (const exception& e) {
    // Handle error
    cerr << e.what() << endl;
}

try-catch Blocks

Basic Syntax

try {
    // Risky code
}
catch (const ExceptionType& e) {
    // Handle specific exception
}
catch (...) {
    // Catch all other exceptions
}

Multiple Catch Blocks

try {
    functionThatMightThrow();
}
catch (const invalid_argument& e) {
    cerr << "Invalid argument: " << e.what() << endl;
}
catch (const out_of_range& e) {
    cerr << "Out of range: " << e.what() << endl;
}
catch (const exception& e) {
    cerr << "Other error: " << e.what() << endl;
}
catch (...) {
    cerr << "Unknown exception" << endl;
}

Nested try-catch

try {
    try {
        throw runtime_error("Inner error");
    }
    catch (const runtime_error& e) {
        // Handle or rethrow
        throw;  // Rethrow same exception
    }
}
catch (const exception& e) {
    cerr << "Caught: " << e.what() << endl;
}

Throwing Exceptions

Throw Statement

// Throw built-in type
throw 42;
throw "Error message";

// Throw standard exception
throw runtime_error("Description");
throw invalid_argument("Bad value");

// Throw custom exception
throw MyException("Custom error");

Rethrowing

catch (const exception& e) {
    // Log it
    log(e.what());

    // Rethrow
    throw;  // Preserves original exception
}

Throw in Functions

int divide(int a, int b) {
    if (b == 0) {
        throw invalid_argument("Division by zero");
    }
    return a / b;
}

try {
    int result = divide(10, 0);
}
catch (const invalid_argument& e) {
    cerr << e.what() << endl;
}

Standard Exceptions

#include <stdexcept>

// Base class
exception

// Logic errors (programmer bugs)
logic_error
  ├── invalid_argument    // Bad argument
  ├── domain_error        // Domain violation
  ├── length_error        // Length exceeded
  └── out_of_range        // Index out of range

// Runtime errors (environment issues)
runtime_error
  ├── range_error         // Range error
  ├── overflow_error      // Arithmetic overflow
  └── underflow_error     // Arithmetic underflow

// Other
bad_alloc               // Memory allocation failed
bad_cast                // Dynamic cast failed
bad_typeid              // typeid on null pointer

Examples

// out_of_range
vector<int> v = {1, 2, 3};
try {
    v.at(10);  // Throws out_of_range
}
catch (const out_of_range& e) { }

// bad_alloc
try {
    int* arr = new int[1000000000000];
}
catch (const bad_alloc& e) { }

// invalid_argument
try {
    stoi("not a number");  // Throws
}
catch (const invalid_argument& e) { }

Custom Exceptions

Inherit from exception

class MyException : public exception {
    string message;
public:
    MyException(const string& msg) : message(msg) {}

    const char* what() const noexcept override {
        return message.c_str();
    }
};

// Usage
throw MyException("Custom error occurred");

Inherit from runtime_error

class FileError : public runtime_error {
public:
    FileError(const string& msg) : runtime_error(msg) {}
};

class NetworkError : public runtime_error {
public:
    NetworkError(const string& msg) : runtime_error(msg) {}
};

Exception with Data

class ValidationError : public exception {
    string field;
    string message;
public:
    ValidationError(const string& f, const string& msg)
        : field(f), message(msg) {}

    const char* what() const noexcept override {
        return message.c_str();
    }

    const string& getField() const { return field; }
};

// Usage
try {
    throw ValidationError("email", "Invalid format");
}
catch (const ValidationError& e) {
    cerr << e.getField() << ": " << e.what() << endl;
}

Exception Specifications

noexcept

// Function won't throw
void safe() noexcept {
    // ...
}

// Conditional noexcept
template<typename T>
void process(T t) noexcept(noexcept(t.operation())) {
    t.operation();
}

// Check at compile time
static_assert(noexcept(safe()), "must be noexcept");

noexcept and Move Operations

class MyClass {
public:
    // noexcept enables optimizations
    MyClass(MyClass&& other) noexcept {
        // Move resources
    }

    MyClass& operator=(MyClass&& other) noexcept {
        // Move assign
        return *this;
    }
};

Best Practices

✅ Do

// 1. Catch by const reference
catch (const exception& e)

// 2. Use RAII for cleanup
{
    unique_ptr<File> file(new File("data.txt"));
    // Exception safe - file closes automatically
}

// 3. Provide useful error messages
throw runtime_error("Failed to connect to " + host + ":" + to_string(port));

// 4. Document throwing functions
/// @throws invalid_argument if value is negative
void setAge(int value);

// 5. Use noexcept for move operations
MyClass(MyClass&&) noexcept;

❌ Don't

// 1. Don't catch by value (slicing)
catch (exception e)  // BAD - slices derived types

// 2. Don't use exceptions for flow control
try {
    while (true) {
        data = getNext();  // Throws when done - BAD
    }
} catch (...) { }

// 3. Don't throw from destructors
~MyClass() {
    throw error;  // BAD - can cause terminate()
}

// 4. Don't catch and ignore silently
catch (...) { }  // BAD - hides errors

// 5. Don't throw raw pointers
throw new MyException();  // Memory leak risk

Quick Reference

// Try-catch
try { }
catch (const Type& e) { }
catch (...) { }

// Throw
throw exception_object;
throw;  // Rethrow current exception

// Standard exceptions
#include <stdexcept>
runtime_error, logic_error
invalid_argument, out_of_range
overflow_error, bad_alloc

// Custom exception
class MyError : public runtime_error {
public:
    MyError(const string& msg) : runtime_error(msg) {}
};

// noexcept
void func() noexcept;
void func() noexcept(condition);
noexcept(expression)  // Check if noexcept

Compile & Run

g++ -std=c++17 -Wall examples.cpp -o examples && ./examples
README - C++ Tutorial | DeepML