문제

기대했다 A::~A() 이 프로그램에서 호출되지만 : 그렇지 않습니다.

#include <iostream>

struct A {
  ~A() { std::cout << "~A()" << std::endl; }
};

void f() {
  A a;
  throw "spam";
}

int main() { f(); }

그러나 마지막 줄을 변경하면

int main() try { f(); } catch (...) { throw; }

그 다음에 A::~A() ~이다 라고 불리는.

Visual Studio 2005에서 "Microsoft (R) 32 비트 C/C ++ 최적화 컴파일러 버전 14.00.50727.762"로 컴파일하고 있습니다. cl /EHa my.cpp.

컴파일러가 평소와 같이 옳습니까? 이 문제에 대해 표준은 무엇을 말합니까?

도움이 되었습니까?

해결책

스택이 풀리기 전에 처리되지 않은 예외를 위해 종료 ()가 호출되기 때문에 파괴자는 호출되지 않습니다.

C ++ 사양이 말하는 내용에 대한 구체적인 세부 사항은 내 지식을 벗어나지 만 GDB와 G ++가있는 디버그 추적은 이것을 설명하는 것 같습니다.

에 따르면 초안 표준 섹션 15.3 탄환 9 :

9 If no matching handler is found in a program, the function terminate()
  (_except.terminate_)  is  called.  Whether or not the stack is unwound
  before calling terminate() is implementation-defined.

다른 팁

C ++ 언어 사양 상태 :시도 블록에서 던지기 표현으로 경로에 구성된 자동 물체에 대한 소멸자를 호출하는 과정을 "스택 풀기"라고합니다. 원래 코드에는 Try Block이 포함되어 있지 않기 때문에 Stack Unding이 발생하지 않습니다.

나는 컴파일러가 언급되지 않았지만 여전히 코드를 생성하지 않지만 여전히 소멸자가 실행해야 할 일을하기 때문에 올바른 행동이 아닙니다.

그래서 VS2008/vc9 (+sp1)에서 시도하고 디버그 및 릴리스를 시도했으며 ~ a는 예외가 발생한 후 F ()에서 나오는 후에 호출됩니다. 이것이 제가 옳다면 올바른 동작입니다.

이제 방금 vs2005/vc8 (+sp1)으로 시도했는데 동일한 동작입니다.

나는 브레이크 포인트를 사용하여 확실하게 사용했습니다. 방금 콘솔을 확인했고 "~ A"메시지도 있습니다. 어쩌면 당신은 다른 곳에서 잘못했을까요?

죄송합니다. 표준 사본이 없습니다.
나는 이것에 대한 확실한 답을 원한다.

내 이해에서 종료는 IFF라고 불립니다.

  • 예외 처리 메커니즘은 예외를 던지기위한 핸들러를 찾을 수 없습니다.
    다음은 더 구체적인 사례입니다.
    • 스택 풀기 동안 예외는 소멸자를 탈출합니다.
    • 던진 표현, 예외는 생성자를 빠져 나갑니다.
    • 예외는 비 지역 정적 (IE Global)의 생성자/소멸자를 피합니다.
    • 예외는 atexit ()에 등록 된 함수를 탈출합니다.
    • 예외는 main ()을 피합니다.
  • 예외가 현재 전파 될 때 예외를 다시 제외하려고합니다.
  • 예상치 못한 예외는 예외를 통해 예기치 않은 지정자가있는 함수를 탈출합니다 (예기치 않은 것을 통해)

이 질문은 Google에게 쉽기 때문에 내 상황을 여기에서 공유합니다.

예전이 교차하지 않도록하십시오 extern "C" 경계 또는 사용 MSVC 옵션 /EHS (C ++ Exeptions 활성화 = 외부 C 함수 ( /EHS)의 예)

두 번째 예에서는 DTOR가 Try {} 블록을 떠날 때 호출됩니다.

첫 번째 예에서, DTOR는 Main () 함수를 떠난 후 프로그램이 종료 될 때 호출됩니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top