2012-01-23 1 views
10

다음 C++ 코드가 있는데 놀랍습니다. 문제는 catch 블록 안에 re-throw 이외의 것을 던지면 프로그램은 abort를 호출하고 GCC4에서 오류 메시지를 내고 " 'int'인스턴스를 throw 한 후 종료됩니다."라는 메시지가 표시됩니다. 방금 ​​"throw;"를 사용하면 catch 블록 안에 다시 던져 넣으면 모든 것이 잘될 것입니다.C++에서 catch 블록 안에 뭔가를 던지면 왜 종료가 발생합니까?

#include <iostream> 
#include <exception> 
#include <stdexcept> 

using namespace std; 

int main() 
{ 
    try{ 
     throw std::string("first throw"); 
    } 
    catch(std::string &x){ 
     try{ 
      std::cout << x << std::endl; 
//   throw; // if I use this line, all is fine. 
      throw int(2); // but if I use this line, it causes Abort() to be called 
     } 
     catch (int &k){ 
      throw; 
     } 
     catch(...) 
     { 
      cout << "all handled here!"<< endl; 
     } 
    } 
    catch(...){ 
     std::cout<< "never printed" << endl; 
    } 
} 
+0

캐치에서 던지면 예상됩니다. – AJG85

답변

7

당신 throw 따라서는 호출되는 abort에 이르게 어떤 try 핸들러 내부 없습니다. 여기

는 들여 쓰기 코드는 비트 및 일부 의견 인라인 정리한다 : 당신이 int를 던질 경우

#include <iostream> 
#include <exception> 
#include <stdexcept> 

using namespace std; 

int main() 
{ 
    try { 
     throw std::string("first throw"); 
    } 
    catch (std::string &x) { 
     try { 
      std::cout << x << std::endl; 
      // throw; // if I use this line, all is fine. 
      throw int(2); // but if I use this line, it causes Abort() to be called 
     } 
     catch (int &k) { 
      // Catches and rethrows exception. Not inside a try thus leads to abort. 
      throw; 
     } 
     catch (...) { 
      // Will handle the case where the string is rethrown instead. No abort. 
      cout << "all handled here!"<< endl; 
     } 
    } 
    catch (...) { 
     std::cout<< "never printed" << endl; 
    } 
} 
+0

고마워, 마틴. 귀하의 의견은 독자들에게 더 분명하게 보여줍니다! –

13

이, 그때는 처리 할 수없는 것이다; 그것을 반역하는 내부의 catch (int &k) 핸들러에 의해 캐치됩니다. 이미 바깥 쪽 catch 블록에 있기 때문에 다시 예외 처리를 잡는 외부 처리기가 없습니다. 따라서이 경우 처리되지 않은 예외로 인해 terminate이 호출됩니다.

string을 다시 제하면 내부의 catch(...) 처리기로 걸러집니다. 이것은 다시 발생하지 않으므로 예외가 처리되었습니다.

+0

고마워요, 마이크. 나는 당신의 대답이 간결하고 정확한 것이라고 생각합니다. –

+0

문자열을 던지는 것이 일반적/권장 관행입니까? –

+0

@StephaneRolland : 보통, 아니요; 로컬에서 처리 할 수없는 오류 또는 기타 조건을보고하기 위해 일반적으로'std :: exception'의 하위 클래스 인 사용자 정의 유형을 throw합니다. 다른 목적으로는 처음에는 예외를 사용하지 않으려 고합니다. 그러나 예외가 어떻게 작동 하는지를 배우기 위해,'string'과'int'는 무엇보다도 좋습니다. –

관련 문제