-
항목14. 예외를 방출하지 않을 함수는 noexcept로 선언하라Effective Modern C++ 2022. 7. 27. 18:02
throw의 대체로써 noexcept으로 선언하면 예외를 방출하지 않는다(예외를 던지면 프로그램이 종료됨). 그래서 예외 방출을 위한 스택 되감기에 따른 스택을 확보할 필요가 없어서 성능 향상에 기여함. noexcept는 예외를 방출하냐 안하냐 라는 이분법적인 정보이다.
std::vector::push_back은 예외 방출 가능성이 있을 때 이동생성자가 호출되면 미정의 행동을 유발할 수 있다. 그래서 예외 방출하지 않는 것이 확실할 때만 이동생성자를 호출한다. (예외 방출 가능성이 있으면 복상생성자가 호출됨 그러면 성능적으로 뒤떨어짐) 이는 noexcept로 선언되어 있는지 여부에 따라 달라짐. (std::vector::push_back의 경우 받는 값이 오른값인지 왼값인지에 따라 달라짐)
noexcept안의 절이 noexcept인지에 의존하는 조건부 noexcept가 있다. 예를 들어 표준 라이브러리에 있는 배열에 대한 swap에 대한 선언들이다.
template <class T, size_t N> void swap(T (&a) [N], T (&b) [N]) noexcept(noexcept(swap(*a, *b)));noexcept안의 noexcept에 있는 swap은 사용자 정의 swap이다. 결과적으로 사용자 정의 swap이 noexcept인지 아닌지에 따라 위 함수의 noexcept여부가 결정된다.
noexcept를 사용하다 나중에 제거하면 클라이언트 코드가 깨질 위험이 생긴다. 따라서 함수의 구현이 예외를 방출하지 않는다는 것을 오랫동안 유지할 확신이 있어야만 noexcept로 선언해야한다.
예외에 중립적인 함수는 noexcept로 선언할 수 없다. 예외에 중립적인 함수란 직접 예외를 호출하지는 않지만 예외를 던지는 함수를 호출하는 함수이다.
대부분의 함수가 이런 함수여서 noexcept가 지정되어 있지 않다.'Effective Modern C++' 카테고리의 다른 글
항목16. const멤버 함수를 스레드에 안전하게 작성하라 (0) 2022.07.29 항목15. 가능하면 항상 constexpr을 사용하라 (0) 2022.07.28 항목13. iterator보다 const_iterator를 선호하라 (0) 2022.07.27 항목12. 재정의 함수들을 override로 선언하라 (0) 2022.07.26 항목11. 정의되지 않은 비공개 함수보다 삭제된 함수를 선호하라 (0) 2022.07.25