2012-10-16 6 views
5

"try & catch"학습. 다음 코드에 어떤 문제가 있습니까? 조언 해 주셔서 감사합니다. 실행에C++ 예외 처리

오류 :

terminate called without an active exception 
Aborted 

코드 :

#include <stdio.h> 
int main() 
{ 
    int a = 3; 

    try 
    { 
    if (a < 5) 
     throw; 
    } 
    catch (...) 
    { 
    printf ("captured\n"); 
    } 

    return 0; 
} 
+0

++ 당신이 선택의 언어로 C++을 선택하면 _ ish_, 단지 C++ 코드에 익숙해, 코드가 쉽게 될 수있는이 방법 : 예를 들어

어떤 유익도없이 언어가 이상하게 혼합되어있어 새롭고 유용한 것을 배우지 않고 삶을 더 열심히 할 수 있습니다. C가 문제없이 C++에서 지원된다는 것은 사실이지만, 코딩 할 때보다 단순하고 훨씬 더 선형적인 접근 방식을 시도하십시오. – Ken

답변

4

같은 뭔가가 필요, 당신은 무엇 던질 지정해야합니다. throw을 사용할 수있는 유일한 장소는 현재 예외를 다시 던지기위한 catch 블록 안에 있습니다. 현재 예외가 발생하지 않고 throw을 단독 호출하면 이미 발견 한 것처럼 앱을 종료합니다.

이 시도 :

#include <stdio.h> 

int main() 
{ 
    int a = 3; 

    try 
    { 
    if (a < 5) 
     throw 1; // throws an int 
    } 
    catch (...) 
    { 
    printf ("captured\n"); 
    } 

    return 0; 
} 

할 수 있습니다만큼 당신이 뭔가를 던져 당신이 원하는 throw 아무것도.

+0

구문 적 제한을 제안하기 때문에 '[catch] 블록 안에서'throw '를 사용해야합니다'라는 말은 다소 모호합니다.실제로 예외가 활성화 될 때마다 범위에 관계없이 다시 제 거할 수 있습니다. –

+0

@LucDanton : 나는 당신이 그 자체로'던짐 '을 사용해야한다고 말하지 않았다, 나는 당신이'쓰레기'를 사용할 수있는 유일한 장소는'잡기 '안에 있다고 말했다. 'catch '내부에 있지 않으면 활성 예외가 없습니다. –

+0

['catch '블록 안에서'throw;'가 구문 적으로 사용되지 않는 정확한 예] (http://liveworkspace.org/code/85bfc976aec21b24d65293ce9355b7cb). –

5

귀하의 throw; 문은 현재 예외를 다시 발생하려고하지만 아마 일이 아니다. 당신은 try 블록의 내부

throw some_exception_object(); 
+2

''throw std :: runtime_error ("message")'를 권하고 싶지만'throw 42'를 보았습니다 ('catch (...) '로만 잡을 수 있다고 생각합니다). –

+1

@MaxLybbert :'catch (int n)'으로 잡힐 수는 있지만, 클래스가 아닌 타입을 던지는 것은 "진짜"프로그램에는 권장되지 않습니다. – aschepler

+0

고마워, 방금 테스트했는데'catch (int i)'가 작동한다. –

1

실제로 어떤 물건을 던져야합니다.

throw "error"; 

과 같은 간단한 것조차도 원하는 오류를 포착합니다.

는 네 가지, 두 가지와 두 개의 작은이있다 행동 here

4

에서 볼. 한 번에 한 가지 ... 활성 예외 O를

throw; 문이 현재 잡힌 예외를 다시 던질하는 데 사용됩니다/w

1. 다시 던진다 사용. 예를 들어 : 귀하의 경우

try { 
    do_something(); 
} catch (const std::exception &) { 
    throw; // This statement re-throws an exception that was caught in this "catch" block. 
} 

, 당신은 예외를 잡기없이 throw;을 사용하는 (주문 단어 -가 직접 또는 간접적으로 catch 블록 내부에 표시되지 않습니다), 따라서 프로그램이 종료됩니다. 예외를 throw 할 필요가 있고 예외를 다시 throw하지 않을 경우, 예외 오브젝트를 지정해야합니다. 예를 들어 :

throw std::runtime_error("Something bad happened"); 

2. 포괄하지 않습니다 절 ++

귀하의 포괄 절 (catch (...))이 완벽하게 합법적 C하다 잡힌 예외 다시는-던져. 그러나 catch 된 예외는 다시 throw되지 않습니다. 합법적 인 C++ 코드이지만 이러한 사용법은 금기 사항입니다. C 및 C++ 런타임은 일반적으로 특정 기능을 구현하기 위해 특수 유형의 예외를 사용합니다. 예를 들어, NPTL은 예외를 사용하여 스레드 취소를 구현합니다. catch (...)을 사용하여 해당 예외를 잡으면 스레드가 취소되지 않고 나쁜 시간을 보게됩니다. 일반적으로 예외를 예외로 catch해야합니다.거의 모든 경우 예외는 std::exception에서 상속되므로 catch (const std::exception &)이나 정확한 유형을 알아 내려는 경우 -으로 작성해야합니다. 그러나 캐치 올을 사용해야하는 경우 다시 던지십시오. 예를 들어 :

try { 
    do_something(); 
} catch (...) { 
    throw; // DO NOT FORGET TO RE-THROW. 
} 

3. 헤더는 C++ 표준 C의 기능에 대한 자신의 헤더를 제공하는 반면 당신은 C 헤더를 포함하는 ...

의 이름을 지정. 그래서, 헤더 :

#include <stdio.h> 

.. 있어야한다 :

#include <cstdio> 

C++ 특정 C 함수는 특별한 치료를받을. 예를 들어, std 네임 스페이스에서 사용할 수 있습니다. 따라서 open() 또는 ::open() 대신 std::open()을 사용할 수 있습니다. 별거 아니지만,가는 것이 좋습니다.

4. 메인에서 돌아 가기.

C와 달리 C++의 main() 기능은 매우 특별합니다. 그것은 당신이 return 0;을 갖지 못하게합니다. 이는 기본 동작입니다. 따라서 어떤 값을 반환해야 할 필요가 없다면 return 0;을 입력하지 않고 시간을 절약 할 수 있습니다. 그러나 main은 그와 같은 유일한 함수이며 함수가 void으로 표시되지 않는 한 어디에서나 명시 적으로 반환해야한다는 것을 기억하십시오.

희망이 있습니다. 행운을 빕니다! 예외가 발생하는

1

문은 다음과 같습니다

throw <expression>; 

이 문 : 또한 다시 throw 문을 불러왔다 기존의 예외를 다시 던질 사용할 수 있습니다

throw; 

붙 잡혔다. 일반적으로 catch 블록에서 사용됩니다. 예를 들어 예외를보고 계속할 수 있는지, 다시 시도할지 또는 중단 할지를 결정합니다. 중단하기로 결정한 경우 예외를 다시 던져 다른 누군가가 호출 스택을 포착하여이 오류를 처리하도록합니다. 코드가 C보다 더 C_ish_을 보이는 방법에 의해

// getResult() calls can fail with a deadlock exception 
// This method will retry up to 3 times before failing 
Result getResultWithRetry() 
{ 
    int nbTry = 3; 
    for(;;) { 
     try { 
      return getResult(); 
     } catch (DeadLockException& e) { 
      if (nbTry == 0) { 
       throw; // re-throw the deadlock exception 
      } 
     } 
     --nbTry; 
    } 
} 
+1

힌트 : 정당한 이유가없는 상수가 아닌 참조로 예외를 잡는 것은 나쁜 습관입니다. 개체를 정말로 수정해야하는 경우가 아니라면 상수 참조로 잡으십시오. 이렇게하면 컴파일러가 더 많은 최적화를 수행 할 수 있습니다. –