How do I design exception-safe code (basic/strong/nothrow guarantees)?

Designing exception-safe code in C++ involves understanding and implementing various levels of guarantees regarding the safety of your code during exceptions. The three main categories are:

  • Basic Guarantee: The program remains in a valid state even if an exception is thrown, but there may be some resources that are not released.
  • Strong Guarantee: Ensures that if an exception is thrown, the state of the program remains unchanged, effectively providing a rollback.
  • Nothrow Guarantee: Guarantees that functions will not throw exceptions, which is crucial for certain types of code where exceptions would be detrimental.

Example: Basic, Strong and Nothrow Guarantees


// Basic Guarantee Example
class BasicSafe {
public:
    BasicSafe() {
        // allocate resources
    }
    
    ~BasicSafe() {
        // release resources, ensuring program remains valid even if destruction fails
    }
    
    void doSomething() {
        // may throw exception; resource may not be fully released
    }
};

// Strong Guarantee Example
class StrongSafe {
public:
    StrongSafe() {
        // allocate resources
    }
    
    ~StrongSafe() {
        // release resources
    }
    
    void doSomething() {
        // use a try-catch block to ensure we rollback state on exception
        try {
            // code that may throw exception
        } catch (...) {
            // rollback any changes
            throw; // rethrow the exception to maintain strong guarantee
        }
    }
};

// Nothrow Guarantee Example
class NothrowSafe {
public:
    NothrowSafe() noexcept {
        // allocate resources without throwing
    }
    
    void doSomething() noexcept {
        // method guarantee it won't throw
    }
};
    

C++ exception safety basic guarantee strong guarantee nothrow guarantee C++ exceptions code design resource management