SoFunction
Updated on 2025-04-06

A brief discussion on exception handling mechanism in c++

The exception handling mechanism of C++ is a structured method for handling program runtime errors. By separating normal logic from error handling code, the code is improved readability and maintainability. Here are detailed descriptions of its core components and working principles:

1. Three keywords for exception handling

1.1 try block

Function: The code segment that wraps the possible throwing of exceptions.

grammar:

try {
    // Code that may throw exceptions}

1.2 throw expression

Function: Throw an exception object (can be of any type, but usually inherited fromstd::exception)。

grammar:

throw exception_object;

1.3 catch block

Function: Catch and handle specific types of exceptions.

grammar:

catch (ExceptionType1& e) {
    // Handle ExceptionType1 exception} catch (ExceptionType2& e) {
    // Handle ExceptionType2 exception} catch (...) { //Catch all exceptions    // Handle unknown exceptions}

2. Exception handling process

  • Throw an exception: the code is executed tothrowWhen  , stop the current function immediately and start stack expansion (Stack Unwinding).

  • Stack Expand:

    • Destruct local objects of the current scope (in reverse order of construction).

    • Find matching upward along the call chaincatchpiece.

  • Catch exception: Find the first matchcatchExecute its code after blocking.

  • Uncaught exception: If no matching one is foundcatchBlock, callstd::terminate()Terminate the procedure.

3. Exception type and capture method

3.1 Standard exception class

The C++ standard library defines a set of exception classes (located at<stdexcept>Header files), both inherited fromstd::exception

  • std::logic_error: Program logic error (such asstd::invalid_argument)。

  • std::runtime_error: Runtime error (such asstd::overflow_error)。

  • Custom exceptions are usually inherited fromstd::exception

    class MyException : public std::exception {
    public:
        const char* what() const noexcept override {
            return "My custom exception";
        }
    };

3.2 Capture method

  • Capture by value: Copy the exception object (may cause slicing problems).

  • Capture by reference: Avoid copying and preserve polymorphism (recommended).

  • Capture by pointer: Memory needs to be managed manually (not recommended).

  • Catch all exceptions:catch (...)(usually used for logging or resource cleaning).

4. Exceptional security

When an exception is thrown, a function needs to ensure that the resource does not leak, which is divided into three levels:

  • Basic Guarantee: After an exception occurs, the program is in a legal state.

  • Strong Guarantee: The operation is either completely successful or rolled back to the state before the operation (transaction semantics).

  • No-throw Guarantee: Promise not to throw any exceptions (usingnoexceptTag).

5. Key mechanisms and precautions

5.1 noexcept keyword

  • Function: Declare the function to not throw exceptions, helping the compiler optimize the code.

  • grammar:

    void func() noexcept; // C++11 rise

5.2 Stack expansion and destruction

  • RAII (Resource Acquisition Is Initialization): Depend on the destructor of the object automatically releases resources (such as smart pointers, file handles).

  • Avoid throwing exceptions in destructors: may cause program termination.

5.3 Performance impact

  • Zero overhead principle: when there is no exception, the code has no additional overhead.

  • Exceeding exceptions is expensive: it involves stack expansion and type matching, avoiding frequent use of general logic for exception handling.

6. Code example

6.1 Basic usage

#include &lt;iostream&gt;
#include &lt;stdexcept&gt;

void riskyOperation(int value) {
    if (value &lt; 0) {
        throw std::invalid_argument("Value cannot be negative");
    }
    // Other operations}

int main() {
    try {
        riskyOperation(-5);
    } catch (const std::invalid_argument&amp; e) {
        std::cerr &lt;&lt; "Error: " &lt;&lt; () &lt;&lt; std::endl;
    } catch (...) {
        std::cerr &lt;&lt; "Unknown error occurred" &lt;&lt; std::endl;
    }
    return 0;
}

6.2 Custom exceptions

#include <exception>
#include <string>

class NetworkError : public std::exception {
private:
    std::string message;
public:
    NetworkError(const std::string& msg) : message(msg) {}
    const char* what() const noexcept override {
        return message.c_str();
    }
};

void connectToServer() {
    throw NetworkError("Connection timeout");
}

7. Best Practices

  • Priority is given to the use of standard exception types to keep the exception hierarchy clear.

  • Catch exceptions by reference to avoid object slicing and polymorphism loss.

  • Use RAII management resources to ensure exceptional security.

  • Avoid throwing exceptions in the constructor unless resources can be completely cleaned.

  • usenoexceptTagging functions that do not throw exceptions, improving performance.

Summarize

C++ exception handling is passedtry/catch/throwProvides a structured error management mechanism, combined with RAII and standard exception classes, which can effectively improve the robustness of the code. Rational use of exception handling requires weighing performance and security, and following exception security levels and best practices.

This is the end of this article about the exception handling mechanism in C++. For more related C++ exception handling content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!