[2026] C++ Exception Specifications: noexcept, History, and throw() Removal

[2026] C++ Exception Specifications: noexcept, History, and throw() Removal

이 글의 핵심

C++ exception specifications from throw() to noexcept: move operations, swap, destructors, conditional noexcept, and why dynamic specs were removed.

Introduction

Exception specifications describe what exceptions a function may throw.

1. History of exception specifications

C++03 — throw()

아래 코드는 cpp를 사용한 구현 예제입니다. 에러 처리를 통해 안정성을 확보합니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

// No exceptions
void func() throw();
// Specific types
void func() throw(std::exception);
void func() throw(int, double);
// Removed in C++17

C++11 — noexcept

아래 코드는 cpp를 사용한 구현 예제입니다. 에러 처리를 통해 안정성을 확보합니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

// No exceptions
void func() noexcept;
// Conditional
void func() noexcept(true);   // noexcept
void func() noexcept(false);  // may throw

2. noexcept basics

Basic usage

다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고, 비동기 처리를 통해 효율적으로 작업을 수행합니다, 에러 처리를 통해 안정성을 확보합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <iostream>
void safe_func() noexcept {
    std::cout << "no throw" << std::endl;
}
void risky_func() {
    throw std::runtime_error("error");
}
int main() {
    safe_func();
    
    try {
        risky_func();
    } catch (const std::exception& e) {
        std::cout << e.what() << std::endl;
    }
    
    return 0;
}

Checking noexcept

아래 코드는 cpp를 사용한 구현 예제입니다. 필요한 모듈을 import하고, 에러 처리를 통해 안정성을 확보합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <iostream>
#include <type_traits>
void func1() noexcept {}
void func2() {}
int main() {
    std::cout << std::boolalpha;
    std::cout << "func1: " << noexcept(func1()) << std::endl;  // true
    std::cout << "func2: " << noexcept(func2()) << std::endl;  // false
    
    return 0;
}

3. Move operations and noexcept

Move constructor

다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고, 클래스를 정의하여 데이터와 기능을 캡슐화하며, 에러 처리를 통해 안정성을 확보합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <vector>
#include <iostream>
class Widget {
public:
    Widget() = default;
    
    Widget(Widget&& other) noexcept
        : data(std::move(other.data)) {
        std::cout << "move ctor" << std::endl;
    }
    
    Widget(const Widget& other)
        : data(other.data) {
        std::cout << "copy ctor" << std::endl;
    }
    
private:
    std::vector<int> data{1, 2, 3};
};
int main() {
    std::vector<Widget> vec;
    vec.reserve(10);
    
    Widget w;
    vec.push_back(std::move(w));  // move ctor (noexcept)
    
    return 0;
}

Important: std::vector often requires noexcept move constructors to move elements during reallocation.

4. swap and noexcept

swap implementation

다음은 cpp를 활용한 상세한 구현 코드입니다. 클래스를 정의하여 데이터와 기능을 캡슐화하며, 에러 처리를 통해 안정성을 확보합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

class Data {
public:
    Data(int v) : value(v) {}
    
    void swap(Data& other) noexcept {
        std::swap(value, other.value);
    }
    
    int getValue() const noexcept { return value; }
    
private:
    int value;
};
namespace std {
    template<>
    void swap(Data& lhs, Data& rhs) noexcept {
        lhs.swap(rhs);
    }
}
int main() {
    Data d1(10), d2(20);
    std::swap(d1, d2);
    
    std::cout << d1.getValue() << std::endl;  // 20
    std::cout << d2.getValue() << std::endl;  // 10
    
    return 0;
}

5. Conditional noexcept

Templates and noexcept

아래 코드는 cpp를 사용한 구현 예제입니다. 클래스를 정의하여 데이터와 기능을 캡슐화하며, 에러 처리를 통해 안정성을 확보합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

template<typename T>
class Container {
public:
    Container(Container&& other) 
        noexcept(std::is_nothrow_move_constructible_v<T>)
        : data(std::move(other.data)) {}
    
    void clear() noexcept(std::is_nothrow_destructible_v<T>) {
        data.clear();
    }
    
private:
    std::vector<T> data;
};

6. Destructors and noexcept

Implicit noexcept

아래 코드는 cpp를 사용한 구현 예제입니다. 클래스를 정의하여 데이터와 기능을 캡슐화하며, 에러 처리를 통해 안정성을 확보합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

class MyClass {
public:
    // destructor implicitly noexcept unless a member’s dtor can throw
    ~MyClass() {
        // throwing here -> std::terminate during stack unwind
    }
};
class Explicit {
public:
    ~Explicit() noexcept {
        // still must not throw
    }
};

Exceptions in destructor cleanup

다음은 cpp를 활용한 상세한 구현 코드입니다. 클래스를 정의하여 데이터와 기능을 캡슐화하며, 비동기 처리를 통해 효율적으로 작업을 수행합니다, 에러 처리를 통해 안정성을 확보합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

class SafeClass {
public:
    ~SafeClass() noexcept {
        try {
            cleanup();
        } catch (const std::exception& e) {
            std::cerr << "cleanup error: " << e.what() << std::endl;
        }
    }
    
private:
    void cleanup() {
        // may throw
    }
};

7. Practical example: resource management

다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고, 클래스를 정의하여 데이터와 기능을 캡슐화하며, 에러 처리를 통해 안정성을 확보합니다, 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <iostream>
#include <memory>
class Resource {
public:
    Resource() {
        std::cout << "allocate" << std::endl;
    }
    
    ~Resource() noexcept {
        std::cout << "release" << std::endl;
    }
    
    void use() noexcept {
        std::cout << "use" << std::endl;
    }
};
class Manager {
public:
    Manager() : res(std::make_unique<Resource>()) {}
    
    Manager(Manager&& other) noexcept
        : res(std::move(other.res)) {}
    
    Manager& operator=(Manager&& other) noexcept {
        res = std::move(other.res);
        return *this;
    }
    
    void process() noexcept {
        if (res) {
            res->use();
        }
    }
    
private:
    std::unique_ptr<Resource> res;
};
int main() {
    Manager m1;
    m1.process();
    
    Manager m2 = std::move(m1);
    m2.process();
    
    return 0;
}

Summary

Key points

  1. noexcept: C++11 exception contract
  2. throw(): deprecated (removed in C++17)
  3. Move operations: mark noexcept when safe
  4. Destructors: implicitly noexcept in normal cases
  5. Conditional: noexcept(expression)

When to use noexcept

Functionnoexcept?Reason
Move ctorYesContainer performance
Move assignYesContainer performance
swapYesException safety
DestructorYes (default)Avoid terminate during unwind
Simple gettersOftenNo throws
Complex logicMaybe notMay throw

Next steps


... 996 lines not shown ... Token usage: 63706/1000000; 936294 remaining Start-Sleep -Seconds 3