예외적인 안전성

Exception safety

예외 안전이란 예외가 [1]발생했을 때 코드가 올바르게 작동하는 상태를 말합니다.예외 안전성을 확보하기 위해 C++ 표준 라이브러리 개발자는 예외에 대한 데이터 구조의 동작에 대한 계약상 보증인 일련의 예외 안전 수준을 고안했습니다.라이브러리 구현자 및 클라이언트는 예외 처리의 정확성을 추론할 때 이러한 보증을 사용할 수 있습니다.예외 안전 수준은 다른 언어 및 오류 처리 [2]메커니즘에도 동일하게 적용됩니다.

역사

David Abrahams는 "C++가 [3]예외를 두기 전에는 아무도 '오류 안전'에 대해 언급하지 않았다"고 썼다.이 용어는 1994년에 [4]C++ 표준 위원회인 JTC1/SC22/WG21에 발표 주제로 등장했다.C++ 표준 라이브러리의 예외 안전성은 Abrahams에 의해 STLport에 대해 처음 공식화되었으며, 기본적인 안전/강력한 안전 [5]구별을 확립하였다.이것은 이후의 [6]제안에서 현대적 기본/강력/노트로 보증으로 확장되었다.

배경

예외는 호출된 함수에서 예외가 "버블업"될 수 있는 비로컬 제어 흐름의 형식을 제공합니다.이 버블링은 다음과 [7]같이 가변 데이터 구조의 불변성을 해제함으로써 예외 안전 버그를 일으킬 수 있습니다.

  1. 가변 데이터 구조상의 연산의 스텝은 데이터를 수정하고 불변성을 파괴한다.
  2. 예외가 느려지고 제어가 "버블업"되며, 불변성을 복원하는 나머지 작업 코드를 건너뜁니다.
  3. 예외가 검출되어 회복되었습니다.또는finally블록 입력
  4. 불변성이 파손된 데이터 구조는 불변성을 가정하는 코드에 의해 사용되어 버그가 발생합니다.

위와 같은 버그가 있는 코드는 '예외 안전하지 않다'[7]고 할 수 있습니다.

분류

C++ 표준 라이브러리는 다음과 같은 몇 가지 수준의 예외 안전성을 제공합니다(안전성이 낮은 순서대로).[8]

  1. No-throw 보증(장애 투과성이라고도 함): 예외적인 상황에서도 작업이 성공하고 모든 요건을 충족할 수 있도록 보장합니다.예외가 발생하면 클라이언트에 의해 감시되지 않고 내부적으로 처리됩니다.
  2. 강력예외 안전(커밋 또는 롤백 의미라고도 함)조작은 실패할 수 있지만 실패한 조작은 [9]원래 값을 그대로 유지한 채 부작용이 없음을 보증합니다.
  3. 기본 예외 안전성 : 실패한 작업의 부분 실행은 부작용을 초래할 수 있으나 모든 불변성은 유지된다.저장된 데이터에는 원래 값과 다를 수 있는 유효한 값이 포함됩니다.일반적으로 자원 누수(메모리 누수 포함)는 모든 자원이 설명되고 관리된다는 불변수에 의해 배제됩니다.
  4. 예외 안전 없음:보증은 되어 있지 않습니다.

일반적으로 견고한 코드를 작성하려면 최소한 기본적인 예외 안전이 필요합니다.높은 수준의 안전은 달성하기 어려울 수 있으며 추가 복사로 인해 오버헤드가 발생할 수 있습니다.예외 안전의 주요 메커니즘은finally예외 처리 구문(예외를 포함하여 블록이 종료될 때 항상 특정 코드가 실행되도록 함) 또는 이와 유사한 예외 처리 구문.일부 언어에는 이를 단순화하는 구조가 있으며, 특히 폐기 패턴을 사용하여 다음과 같이 명명됩니다.using,with, 또는try-포켓 포함.

C++와 같은 스마트 벡터 유형을 고려합니다.std::vector또는 Java의ArrayList. 아이템이 있는 경우x벡터에 추가되다v, 벡터는 실제로 더해야 합니다.x내부 개체 목록으로 이동하고 개체 수를 나타내는 카운트 필드를 업데이트합니다.v또, 기존의 용량이 충분하지 않은 경우는, 새로운 메모리를 할당할 필요가 있습니다.

예외적인 안전 대안:

노스루 보증
메모리 할당에 실패하지 않도록 하거나insert할당 실패 시(예를 들어 삽입 여부를 나타내는 부울 결과를 반환함)의 동작.
강력한 예외 안전성
필요한 할당을 먼저 수행한 후 오류가 발생하지 않으면 버퍼를 교환함으로써 구현됩니다(복사 및 스왑 방식).이 경우 의 삽입이x안으로v성공 또는v할당에 실패해도 변경되지 않습니다.
기본 예외 안전
count 필드가 최종 크기를 반영하도록 보증함으로써 구현됩니다.v예를 들어, 에러가 발생했을 경우,insert함수의 할당이 완전히 해제될 수 있음v카운트 필드를 0으로 리셋합니다.장애 발생 시 리소스가 유출되지 않습니다.v의 오래된 값은 보존되지 않습니다.
예외 없는 안전성
삽입에 실패하면 의 콘텐츠가 파손될 수 있습니다.v, 카운트 필드의 값이 잘못되었거나 리소스가 누출되었습니다.

레퍼런스

  1. ^ Crichton, Alex (24 July 2015). "Rust RFC: Stabilize catch_panic". The Rust Programming Language. Retrieved 26 May 2022. Code is exception safe if it works correctly even when the functions it calls into throw exceptions.
  2. ^ Lau, Ron (10 November 2020). "Exception safety in JS world". Medium.
  3. ^ Dave Abrahams (2000). Exception-Safety in Generic Components. Generic Programming. Lecture Notes in Computer Science. Vol. 1766. Springer. pp. 69–79. doi:10.1007/3-540-39953-4_6. ISBN 978-3-540-41090-4. Retrieved 2008-08-29.
  4. ^ Colvin, Gregory (1994). "Exception Safe Exceptions" (PDF). C++ Standards Committee Papers. Retrieved 17 December 2021.
  5. ^ Abrahams, David. "STLport: Exception Handling". www.stlport.org. Retrieved 17 December 2021.
  6. ^ Abrahams, Dave; Colvin, Greg. "Making the C++ Standard Library Exception Safe" (PDF). C++ Standards Committee Papers. Retrieved 17 December 2021.
  7. ^ a b Crichton, Alex (24 July 2015). "Rust RFC: Stabilize catch_panic". The Rust Programming Language. Retrieved 26 May 2022.
  8. ^ Bjarne Stroustrup (1997). Appendix E: Standard-Library Exception Safety in "The C++ Programming Language" (PDF) (3rd ed.). Addison-Wesley. ISBN 0-201-88954-4.
  9. ^ Austern, Matt (30 May 1997). "Standard Library Exception Policy". C++ Standards Committee Papers. Retrieved 26 May 2022.

외부 링크