C ++ 03 throw () 지정자 C ++ 11 noexcept의 차이점


100

어떤 차이가 있습니까 throw()noexcept각각 런타임 및 컴파일 시간에 확인하는 것 외에는는?

이 Wikipedia C ++ 11 기사 에서는 C ++ 03 throw 지정자가 더 이상 사용되지 않음을 제안합니다.
왜 그렇다면 noexcept컴파일 타임에 모든 것을 다룰 수 있습니까?

[참고 : 나는 확인 이 질문 하고 이 문서를 하지만, 중단에 대한 고체 이유를 판별 할 수 없습니다.]


7
이에 Accodring 좋은 글은 또한 noexcept런타임 검사를 발생할 수 있습니다. 그들 사이의 주요 차이점은 파괴가 noexcept원인이 std::terminate되는 반면 파괴가 throw원인이라는 것 std::unexpected입니다. 또한 이러한 경우 스택 해제 동작이 약간 다릅니다.
Fiktik

다른 것에서 "런타임"이 확인되는 일부 예외 사양으로 확인 된 "컴파일 시간"이 없습니다. C ++ 예외 사양에 반대하는 사람들이 만든 신화 ​​일뿐입니다.
curiousguy

답변:


129

예외 지정 자는 일반적으로 끔찍한 아이디어 이기 때문에 예외 지정자는 사용되지 않습니다 . noexcept예외 지정자의 합리적으로 유용한 사용이기 때문에 추가되었습니다. 함수 예외를 throw 하지 않을 때를 아는 입니다. 따라서 그것은 이진 선택이됩니다 : 던질 함수와 던지지 않을 함수.

noexcept더 강력 throw()하기 때문에 모든 throw 지정자를 제거하는 대신 추가되었습니다 noexcept. noexcept컴파일 시간이 부울로 해석되는 매개 변수를 가질 수 있습니다. 부울이 참이면 noexcept스틱입니다. 부울이 거짓 noexcept이면가 고정되지 않고 함수가 throw 될 수 있습니다.

따라서 다음과 같이 할 수 있습니다.

struct<typename T>
{
  void CreateOtherClass() { T t{}; }
};

합니까 CreateOtherClass던져 예외? T의 기본 생성자가 할 수 있다면 할 수 있습니다. 우리는 어떻게 말합니까? 이렇게 :

struct<typename T>
{
  void CreateOtherClass() noexcept(is_nothrow_default_constructible<T>::value) { T t{}; }
};

따라서 CreateOtherClass()주어진 유형의 기본 생성자가 던지면 던질 것입니다. 이는 예외 지정자의 주요 문제 중 하나 인 호출 스택을 전파 할 수없는 문제를 해결합니다.

으로이 작업을 수행 할 수 없습니다 throw().


어쨌든 나를 위해 유용한 답변 +1. 여전히 내가 사용하고 싶은 이유에 대한 답변을 찾고 있습니다 noexcept. 나는 throw()지정자를 사용하지 않았으며 noexcept실제로 어떤 이점을 제공 하는지 확인하려고 시도하고 있습니다 (컴파일러 확인 문서 제외).
hmjd 2013

방금이 stackoverflow.com/questions/10787766/…을 찾았습니다. ...
hmjd

1
@NicolBolas는 동의합니다. 그러나 noexcept가 보장된다면 컴파일러는 함수가 소멸자에서 throw되는지 여부를 확인할 수 있습니다. 따라서 프로그래머에게 함수가 예외가 아니라는 것을 경고 할 수 있습니다.
Alex

2
@NicolBolas 런타임 호출 std::terminate. 그것은 정말 최악입니다 ! 코드는 기능이 표시 noexcept 되고 런타임 (고객 사이트에서 의미) 위반이 감지 된 릴리스에 잠입 할 수 있습니다 . 나는 컴파일러 가 처음에 예외를 던지지 않는 코드를 생성하도록 보장한다는 것을 의미했습니다 .
Alex

2
@NicolBolas : 주목할만한 또 다른 차이점이 있습니다. 기능이 표시되어있는 경우 throws(), 예외가 발생하는 경우 다음 스택 해야 하는 포인트가 그 기능 (기능 모두 자동 변수가 파괴되도록) 개까지의 범위 일 풀어진 terminate()(통해 호출된다 unexpected()). 함수가 표시 noexcept되면 예외가 발생하면 종료가 호출됩니다 (스택 해제는 구현 정의 세부 사항 임).
Martin York

33

noexcept 컴파일 타임에 확인되지 않습니다.

구현은 단지 실행될 때 포함하는 함수가 허용하지 않는 예외를 던지거나 던질 수 있기 때문에 표현식을 거부해서는 안됩니다.

함수가 선언 noexcept되거나 throw()예외를 던지려고 할 때 유일한 차이점은 하나의 호출 terminate과 다른 호출 unexpected과 후자의 예외 처리 스타일이 효과적으로 사용되지 않는다는 것 입니다.


그러나 가상 함수에 throw()/가있는 noexcept경우 컴파일 시간 검사에서 재정 의자도 있는지 확인합니다.
curiousguy

2

std::unexpected() 동적 예외 사양이 위반 될 때 C ++ 런타임에 의해 호출됩니다. 예외 사양이이 유형의 예외를 금지하는 함수에서 예외가 throw됩니다.

std::unexpected() 프로그램에서 직접 호출 할 수도 있습니다.

두 경우 모두 std::unexpected현재 설치된를 호출합니다 std::unexpected_handler. 기본 std::unexpected_handler호출 std::terminate입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.