[C/C++] noexcept

그림자왕국·2020년 10월 26일
0

C++

목록 보기
6/24
post-thumbnail

noexcpet


noexcpet 키워드는 예외처리를 진행하지 않는다고 명시적으로 선언할 때 사용된다.

다음과 같은 코드는 noexcpet 처리가 되어있지않아 복사 생성자가 호출된 것이다.

 foo(foo&& other) : value(std::move(other.value))
    {
        other.value = -1;
        std::cout << "foo(move(foo(" << value << "))\n";
    }
 
  foo(foo const& other) : value(other.value)
    {
        std::cout << "foo(foo(" << value << "))\n";
    }
     
   foo fa("name"); // 이동 생성자가 아닌 복사 생성자가 호출됨.

STL 컨테이너들은 move semantics를 지원하는데 원소에 대한 이동 처리를 할 때

해당 원소가 move시 noexcept를 지원하지 않으면, move semantics가 아닌 copy semantics로
element를 처리한다.

이동 생성자 대신 복사 생성자가 호출된 이유는 클래스를 정의할 때 예외처리가 날 수도 있어서
컴파일러가 안전하게 프로그램을 짜기 위해 Move 대신 Copy 생성자를 불러오기 때문이다.

즉, 이동 처리에 대한 strong exception guarantee가 뒷받침 되어 있지 않으면
move semantics을 포기하고 대신 안전한 copy semantics로 처리하겠다는 거다.
(move는 데이터를 옮기는 것이니 예외 처리가 발생할 수 있음)


결 론

move 생성자를 사용하려면 move시 예외처리가 일어날 일이 없다는 걸 보장 해야한다.

(또는 예외가 일어나도 괜찮다는 조약) 이러한 보증으로 noexcept 키워드를 사용한다.

noexcpet는 예외처리를 하지 않아도 괜찮다는 뜻이며, 컴파일러는 이동 생성자를 호출한다.

foo(foo&& other) noexcept : value(std::move(other.value))
    {
        other.value = -1;
        std::cout << "foo(move(foo(" << value << "))\n";
    }
    
foo fa("name"); // 이동 생성자가 호출된다.

가령 std 라이브러리인 vector 같은 경우 move 함수가 noexcept 인지 조사하여

그렇지 않을경우 move 대신 copy 를 이용하므로 noexcept를 꼭 붙이는게 필요하다.

profile
언리얼 엔진 매니아입니다.

0개의 댓글