1. Item 14. 예외를 방출하지 않을
함수는 noexcept로 선언하라
Effective Modern C++ 스터디
이데아 게임즈 손진화
2. 예외 명세(exception specification)
• 함수를 호출할 때 사용자는 호출하는 함수가
어떤 예외를 발생시키는지 알아야 한다
• C++11에서는 사용하는 함수가 예외를 발생
시키지 않을 수 있다고 보장 할 경우
noexcept 키워드를 사용할 수 있다
3. 예외를 발생시키지 않는 함수
• int f(int x) throw() // C++ 98
• Int f(int x) noexcept // C++ 11
4. 만약 에러가 났을 경우
• throw() // C++ 98
스택 풀기(stack unwind)를 시도하다가 에러 처리
코드를 만나지 못하면 실행이 종료된다
• noexcept
- 스택 풀기 수행 여부는 컴파일러마다 다르다
- VS 에서는 에러 처리 코드가 있어도 프로그램이
종료된다
5. 최적화 정도
• Int f(int x) noexcept
최적화 여지가 가장 크다
• int f(int x) throw()
최적화 여지가 더 작다
• int f(int x)
최적화 여지가 더 작다
8. 예제 - 해결
• 예외 발생이 가능한 경우는 move대신 copy
를 한다
• 예외가 발생하지 않는다고 확인되면 move를
사용한다
• 예외 발생 여부는 noexcept 키워드로
지정하면 된다
9. 예제 - 해결
• C++98에서 강한 예외 안전성을 보장하는 함
수들 중에 이런 식으로 동작하는 함수들은 모
두 C++11에서 이렇게 동작하도록 수정되었
다
• std::vector::reserve
std::vector::insert
td::deque::insert
11. noexcept 를 잘 생각하고 사용하자
• noexcept 함수 였다가 후에 바뀌는 경우
• 예외 중립적 함수인 경우
• noexcept를 쓰기 위해 함수 내부에서
예외처리 등을 많이 해두어서 성능상 이득을
못 보는 경우
12. noexcept 를 잘 생각하고 사용하자
• 메모리 해제 함수와 모든 소멸자는 암묵적으
로 noexcept로 선언된다
만약에 바꾸고 싶은 경우 noexcept(false)
사용
• 넓은 계약을 가진 함수들에 대해서만
noexcept 키워드를 사용
void f(const std::string& s) noexcept;
// 전제조건 : s.length() <= 32
13. 넓은 계약, 좁은 계약
• 넓은 계약
함수를 호출하기 위한 사전 조건이 존재하지
않는다.
• 좁은 계약
넓은 계약을 만족하지 못하는 모든 경우
• 미정의 행동
하지 말라는 행동..
14. noexcept 를 잘 생각하고 사용하자
• 함수 구현과 예외 명세 사이를 컴파일러가
파악해주지 않는다
void setup();
void cleanup();
void init() noexcept
{
setup();
// …
cleanup();
} // ok
15. 결론
• noexcept는 함수의 인터페이스의 일부이다
이는 호출자가 noexcept 여부에 의존할 수
있음을 뜻한다
• noexcept 함수는 비noexcept함수보다
최적화의 여지가 크다
16. 결론
• noexcept는 이동 연산들과 swap,
메모리 해제 함수들, 그리고 소멸자들에
특히나 유용하다
• 대부분의 함수는 noexcept가 아니라 예외에
중립적이다