>백엔드 개발 >C++ >C가 소멸자에서 발생한 예외를 처리하기 위해 중첩된 예외를 사용하지 않는 이유는 무엇입니까?

C가 소멸자에서 발생한 예외를 처리하기 위해 중첩된 예외를 사용하지 않는 이유는 무엇입니까?

Barbara Streisand
Barbara Streisand원래의
2024-11-01 01:29:02454검색

Why doesn't C   use nested exceptions to handle exceptions thrown from destructors?

C가 소멸자에서 예외를 발생시키기 위해 중첩된 예외를 사용하지 않는 이유는 무엇입니까?

문제 이해

소멸자에서 예외 발생 딜레마가 발생합니다. 예외가 이미 진행 중인 경우 어떻게 해야 할까요? 기존 예외를 덮어쓰거나 기존 예외 내에 새 예외를 중첩하는 것이 잠재적인 해결책이지만 std::terminate로 종료하는 것이 표준 접근 방식이 될 것으로 결정되었습니다.

중첩 예외 고려

C 11에서는 std::nested_Exception 기능을 도입했습니다. 이 기능은 이전 예외를 새 예외 내에 중첩시켜 잠재적으로 문제를 해결할 수 있습니다. 그러나 이 아이디어는 구현되지 않았습니다.

구현되지 않은 이유

이 맥락에서 중첩 예외를 사용하지 않는 한 가지 이유는 std::nested_Exception이 매우 제한적으로 사용되며 알려진 실제 애플리케이션은 완전히 주석이 달린 호출 스택 생성입니다.

이 예에서는 중첩 예외가 디버깅 중에 컨텍스트를 추가하고 오류를 찾아내는 편리한 방법을 제공하는 방법을 보여줍니다.

<code class="cpp">#include <iostream>
#include <sstream>
#include <exception>

void rethrow(const std::string& context, ...) {
    std::ostringstream ss;
    ss << context;
    auto sep = " : ";
    (void) ((ss << sep << args), sep = ", ", 0)...);
    try {
        std::rethrow_exception(std::current_exception());
    } catch(const std::invalid_argument& e) {
        std::throw_with_nested(std::invalid_argument(ss.str()));
    } catch(const std::logic_error& e) {
        std::throw_with_nested(std::logic_error(ss.str()));
    } catch(...) {
        std::throw_with_nested(std::runtime_error(ss.str()));
    }
}

int main() {
    try {
        outer("xyz");
        outer("abcd");
    } catch(std::exception& e) {
        print_exception(e);
    }
    return 0;
}

void print_exception(const std::exception& e, std::size_t depth = 0) {
    std::cerr << "exception: " << std::string(depth, ' ') << e.what() << '\n';
    try {
        std::rethrow_if_nested(e);
    } catch (const std::exception& nested) {
        print_exception(nested, depth + 1);
    }
}</code>

예상 출력:

exception: outer : abcd
exception:  inner : abcdabcd
exception:   really_inner
exception:    too long

위 예에서는 예외 중첩을 보여주고 이 기술이 오류 추적 및 호출 스택 이해에 어떻게 도움이 되는지 보여줍니다.

이 예제에서는 중첩된 예외의 유용성에도 불구하고 특정 시나리오에서는 소멸자 예외의 맥락에서 이를 사용하지 않기로 결정한 이유는 std::terminate를 사용한 종료의 용이성과 안정성 때문일 것입니다.

위 내용은 C가 소멸자에서 발생한 예외를 처리하기 위해 중첩된 예외를 사용하지 않는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.