예외적인 안전성
Exception safety예외 안전이란 예외가 [1]발생했을 때 코드가 올바르게 작동하는 상태를 말합니다.예외 안전성을 확보하기 위해 C++ 표준 라이브러리 개발자는 예외에 대한 데이터 구조의 동작에 대한 계약상 보증인 일련의 예외 안전 수준을 고안했습니다.라이브러리 구현자 및 클라이언트는 예외 처리의 정확성을 추론할 때 이러한 보증을 사용할 수 있습니다.예외 안전 수준은 다른 언어 및 오류 처리 [2]메커니즘에도 동일하게 적용됩니다.
역사
David Abrahams는 "C++가 [3]예외를 두기 전에는 아무도 '오류 안전'에 대해 언급하지 않았다"고 썼다.이 용어는 1994년에 [4]C++ 표준 위원회인 JTC1/SC22/WG21에 발표 주제로 등장했다.C++ 표준 라이브러리의 예외 안전성은 Abrahams에 의해 STLport에 대해 처음 공식화되었으며, 기본적인 안전/강력한 안전 [5]구별을 확립하였다.이것은 이후의 [6]제안에서 현대적 기본/강력/노트로 보증으로 확장되었다.
배경
예외는 호출된 함수에서 예외가 "버블업"될 수 있는 비로컬 제어 흐름의 형식을 제공합니다.이 버블링은 다음과 [7]같이 가변 데이터 구조의 불변성을 해제함으로써 예외 안전 버그를 일으킬 수 있습니다.
- 가변 데이터 구조상의 연산의 스텝은 데이터를 수정하고 불변성을 파괴한다.
- 예외가 느려지고 제어가 "버블업"되며, 불변성을 복원하는 나머지 작업 코드를 건너뜁니다.
- 예외가 검출되어 회복되었습니다.또는
finally
블록 입력 - 불변성이 파손된 데이터 구조는 불변성을 가정하는 코드에 의해 사용되어 버그가 발생합니다.
위와 같은 버그가 있는 코드는 '예외 안전하지 않다'[7]고 할 수 있습니다.
분류
C++ 표준 라이브러리는 다음과 같은 몇 가지 수준의 예외 안전성을 제공합니다(안전성이 낮은 순서대로).[8]
- No-throw 보증(장애 투과성이라고도 함): 예외적인 상황에서도 작업이 성공하고 모든 요건을 충족할 수 있도록 보장합니다.예외가 발생하면 클라이언트에 의해 감시되지 않고 내부적으로 처리됩니다.
- 강력한 예외 안전(커밋 또는 롤백 의미라고도 함)조작은 실패할 수 있지만 실패한 조작은 [9]원래 값을 그대로 유지한 채 부작용이 없음을 보증합니다.
- 기본 예외 안전성 : 실패한 작업의 부분 실행은 부작용을 초래할 수 있으나 모든 불변성은 유지된다.저장된 데이터에는 원래 값과 다를 수 있는 유효한 값이 포함됩니다.일반적으로 자원 누수(메모리 누수 포함)는 모든 자원이 설명되고 관리된다는 불변수에 의해 배제됩니다.
- 예외 안전 없음:보증은 되어 있지 않습니다.
일반적으로 견고한 코드를 작성하려면 최소한 기본적인 예외 안전이 필요합니다.높은 수준의 안전은 달성하기 어려울 수 있으며 추가 복사로 인해 오버헤드가 발생할 수 있습니다.예외 안전의 주요 메커니즘은finally
예외 처리 구문(예외를 포함하여 블록이 종료될 때 항상 특정 코드가 실행되도록 함) 또는 이와 유사한 예외 처리 구문.일부 언어에는 이를 단순화하는 구조가 있으며, 특히 폐기 패턴을 사용하여 다음과 같이 명명됩니다.using
,with
, 또는try
-포켓 포함.
예
C++와 같은 스마트 벡터 유형을 고려합니다.std::vector
또는 Java의ArrayList
. 아이템이 있는 경우x
벡터에 추가되다v
, 벡터는 실제로 더해야 합니다.x
내부 개체 목록으로 이동하고 개체 수를 나타내는 카운트 필드를 업데이트합니다.v
또, 기존의 용량이 충분하지 않은 경우는, 새로운 메모리를 할당할 필요가 있습니다.
예외적인 안전 대안:
- 노스루 보증
- 메모리 할당에 실패하지 않도록 하거나
insert
할당 실패 시(예를 들어 삽입 여부를 나타내는 부울 결과를 반환함)의 동작. - 강력한 예외 안전성
- 필요한 할당을 먼저 수행한 후 오류가 발생하지 않으면 버퍼를 교환함으로써 구현됩니다(복사 및 스왑 방식).이 경우 의 삽입이
x
안으로v
성공 또는v
할당에 실패해도 변경되지 않습니다. - 기본 예외 안전
- count 필드가 최종 크기를 반영하도록 보증함으로써 구현됩니다.
v
예를 들어, 에러가 발생했을 경우,insert
함수의 할당이 완전히 해제될 수 있음v
카운트 필드를 0으로 리셋합니다.장애 발생 시 리소스가 유출되지 않습니다.v
의 오래된 값은 보존되지 않습니다. - 예외 없는 안전성
- 삽입에 실패하면 의 콘텐츠가 파손될 수 있습니다.
v
, 카운트 필드의 값이 잘못되었거나 리소스가 누출되었습니다.
레퍼런스
- ^ 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.
- ^ Lau, Ron (10 November 2020). "Exception safety in JS world". Medium.
- ^ 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.
- ^ Colvin, Gregory (1994). "Exception Safe Exceptions" (PDF). C++ Standards Committee Papers. Retrieved 17 December 2021.
- ^ Abrahams, David. "STLport: Exception Handling". www.stlport.org. Retrieved 17 December 2021.
- ^ Abrahams, Dave; Colvin, Greg. "Making the C++ Standard Library Exception Safe" (PDF). C++ Standards Committee Papers. Retrieved 17 December 2021.
- ^ a b Crichton, Alex (24 July 2015). "Rust RFC: Stabilize catch_panic". The Rust Programming Language. Retrieved 26 May 2022.
- ^ Bjarne Stroustrup (1997). Appendix E: Standard-Library Exception Safety in "The C++ Programming Language" (PDF) (3rd ed.). Addison-Wesley. ISBN 0-201-88954-4.
- ^ Austern, Matt (30 May 1997). "Standard Library Exception Policy". C++ Standards Committee Papers. Retrieved 26 May 2022.
외부 링크
- 허브 서터:Excellent C++: 47개의 엔지니어링 퍼즐, 프로그래밍 문제 및 솔루션, 2000
- 존 칼브:C++에서의 예외적인 안전한 코딩, C++Now!예외 안전성에 대한 2012년 프레젠테이션.
- Stackoverflow 관련 설명:C++: 예외 안전 코드를 작성하시겠습니까?