5

그래서 일부 코드를 작성했지만 구문, 유형 및 기타 컴파일 타임 오류를 제외하면 C++에서 다른 예외는 발생하지 않습니다. 그래서 아주 사소한 프로그램이 테스트하기로 결정C++ 예외 처리

내가 g의 ++를 사용하여 컴파일 된
#include<iostream> 

int main() { 
    std::count<<5/0<<std::endl; 
return 1 
} 

는, g ++ 내가 0으로 분할되었다하지만 여전히 코드를 컴파일 말을 나에게 경고했다. 그럼 내가 달렸을 때 정말 큰 임의 번호를 인쇄 했어. 내가 알고 싶을 때, C++이 예외를 어떻게 처리합니까? 0으로 정수 나누기 예외가 throw되어야하고 프로그램을 종료해야 할 때 매우 간단한 예입니다.

필자의 전체 프로그램을 거대한 try 블록에 넣고 일정한 예외를 잡아야합니까? 파이썬에서 예외가 발생하면 프로그램이 즉시 종료되고 오류를 출력합니다. C++은 무엇을합니까? 실행을 멈추고 프로그램을 종료하는 런타임 예외가 있습니까?

답변

8

런타임 예외가 있지만 "잘못된"모든 결과가 런타임 예외가 발생하는 것은 아닙니다. 예를 들어, 범위를 벗어나는 배열에 액세스하거나 널 포인터를 역 참조하는 것은 단순히 "정의되지 않은 동작"입니다. 전혀 의미가 없습니다. 0으로 나눈 값은 "정의되지 않은"범주에 속합니다.

예외가 아닌 "정의되지 않은 동작"을 초래하는 일부 연산에 대한 이론적 근거는 효율성입니다. 범위를 벗어난 배열에 액세스하려면 예외가 발생해야한다고 가정합니다. 그런 다음 컴파일러는 범위 외인지 여부를 확인하기 위해 각 배열 액세스에 대한 코드를 생성해야합니다. 그렇다면 예외를 throw합니다. 그것은 많은 검사이며, 대부분은 불필요합니다. 대신, 컴파일러가 수행하는 작업은 요소 액세스에 대한 명령을 범위 내에 있다고 가정하여 생성하는 것입니다. 범위를 벗어나는 경우 발생하는 모든 상황 (예 : 세분화 오류)이 발생합니다. 점검을 수행하려면 항상 명시 적으로 코드를 작성할 수 있습니다.

이렇게하면 수표를 언제 원하는지 선택할 수 있기 때문에 항상 수표 (예 : Java 또는 Python)를 사용하는 언어보다 C++이 더 강력 해집니다. (반면에 C++은 자바 나 파이썬보다 안전하지 못하다. 예외가 발생하지만, 어느 곳 적발되지 않을 때 어떻게되는지에 관해서는


는 일반적으로 컴파일러 구현을 포함하는 오류 메시지가 인쇄됩니다 예외의 what(). 귀하의 예제에서는 런타임 예외가 발생하지 않기 때문에 해당되지 않습니다.

+0

고마워. 다른 질문입니다. std :: cout 대신 std :: cerr을 사용하면 예외가 발생하거나 오류 스트림으로 인쇄됩니까? 그리고 만약 내 자신의 예외 (foo라고 말하면)를 만들고 내 코드에서 foo를 던지면 내 프로그램이 즉시 죽을 것이고 foo.what()는 출력 될 것인가? 아니면 명시 적으로 C++에 그렇게해야합니까? – user1413793

+0

@ user1413793 :'std :: cerr'에 쓰면 단순히 오류 스트림으로 출력됩니다. 명령 행 ('>'vs'2>')에서 리다이렉션을 통해 다른 곳으로 출력 스트림과 오류 스트림을 보낼 수 있습니다. 예외를 던지면 아무데도 잡히지 않으면 프로그램이 즉시 종료되고 오류 메시지가 출력됩니다. (보다 정확하게는'std :: terminate'라는 함수가 호출됩니다.이 함수의 기본 동작은 프로그램을 종료하고 예외 메시지를 출력하는 것이고,'std :: set_terminate'를 호출하여 동작을 무시할 수 있습니다. 관심 있어요.) – HighCommander4

0

Visual C++에서는이 값을 0으로 나누기 오류로 올바르게 플래그 지정합니다. 컴파일하지 않으면 실행하는 데 문제가 없습니다.

+0

에 대답하지만 "올바른"인가? 그냥 궁금해서. –

+0

0으로 나누는 것은 표준보다 먼저 정의되지 않았습니까? – Superman

3

예, 런타임 예외가 있습니다. 예를 들어 에 의해 던져진 out_of_range입니다.

그러나, 0으로 나누기는 (C++ 0X §5.6/4) 정의되지 않는다 :

/또는 %의 두 번째 오퍼랜드는 문제가 운데 인터넷 네드 제로이면.

따라서는 만들어 낸 예외를 던져, "정말 큰 임의의 수", 또는 세그먼트 폴트를 인쇄 컴파일 실패 할 수 있습니다.

+0

감사합니다. 나는 다른 언어가 예외를 던지기 때문에 혼란 스러웠다.하지만 이해가된다. – user1413793

2

C++은 C++ 표준에서 잘 정의 된 표준 예외 만 throw합니다.표준 C++ 예외 (기술적으로 그것이 정의되지 않은 동작)하지

정수를 0으로 나눈 값 (예는 일부 런타임 예외를 포함). 따라서 암시 적 예외는 발생하지 않습니다. 특정 컴파일러는 런타임 오류를 일종의 예외로 매핑 할 수 있습니다 (컴파일러 문서에서이 예외를 확인해야합니다. 일부 컴파일러는 0으로 나누기도합니다). 그러나이 방법은 이식성이 없으며 모든 컴파일러에서 작동하지 않습니다.

가장 좋은 방법은 오류 조건 (제수가 0 임)을 확인하고 이러한 경우 명시 적으로 예외를 throw하는 것입니다.

편집 : 표준에 따라이 주석

class A 
{ 
    public: 
     void f() 
     { 
      int x; 
      //For illustration only 
      int a = 0; 
      if(a == 0) 
        throw std::runtime_error("Divide by zero Exception"); 
      x=1/a; 
     } 

     A() 
     { 
       try 
       { 
        f(); 
       } 
       catch(const std::runtime_error& e) 
       { 
        cout << "Exception caught\n"; 
        cout << e.what(); 
       } 
     } 
};  
+0

예외가 발생하여 프로그램이 종료되고 예외가 인쇄되거나 예외를 catch하고 명시 적으로 C++에게 무엇을 지시해야합니까? – user1413793

+1

@ user1413793 : 답변을 업데이트했습니다. 예외를 잡아서 어떻게해야할지 결정해야합니다. –