C++에서 예외 처리 및 소멸자 예외를 사용하여 더 잘 이해하고 있으며 설명 할 수없는 이상한 동작이 발생했습니다. 나를 도와 줄 수 있니).MSVC의 소멸자에서 예외를 throw하는 예외
이 간단한 코드를 작성했습니다. 이것은 예외 클래스 (Foo)로, 파기 될 때 자신을 버립니다. 여기서 의도는 main()으로 던져진 곳에서 예외를 전파하는 것입니다. main()에서는 예외를 명시 적으로 catch하고 재실행을 중단합니다.
#include <iostream>
class Foo
{
public:
Foo();
virtual ~Foo();
void stopThrowing() { keepThrowing_ = false; }
private:
bool keepThrowing_;
};
Foo::Foo(): keepThrowing_(true)
{
std::cout << "Foo created: " << this << std::endl;
}
Foo::~Foo()
{
std::cout << "Foo destroyed: " << this << std::endl;
if (keepThrowing_)
{
throw Foo();
}
}
int main()
{
try {
try {
throw Foo();
} catch (const Foo&) {
std::cout << "Foo caught" << std::endl;
}
} catch (Foo& ex) {
std::cout << "Foo caught 2" << std::endl;
ex.stopThrowing();
} catch (...) {
std::cout << "Unknown exception caught 2" << std::endl;
}
std::cout << "Done" << std::endl;
return 0;
}
나는이 C++에서 수행해서는 안됩니다 알고 있지만 요점은 그게 아니다 - 나는 내가 설명 할 것 같은 (MSVC에서 x86 및 x64 예외 처리 사이의 차이가 무엇인지 이해하기 위해 노력하고있어 다음 단락).
내가 MSVC를 사용하여 86이 코드를 컴파일
는 (나는 주로 2010을 사용하지만, 나는 또한 2005 년과 2012 년이 체크), 모든 것이 괜찮 그것은 예상대로 작동합니다Foo created: 001AFC1C
Foo caught
Foo destroyed: 001AFC1C
Foo created: 001AF31C
Foo caught 2
Foo destroyed: 001AF31C
Done
내가 컴파일 할 때 MSVC를 사용하여 64이 코드는, 그것은 심하게 실패
Foo created: 000000000047F9B8
Foo caught
Foo destroyed: 000000000047F9B8
Foo created: 000000000047D310
Foo destroyed: 000000000047D310
Foo created: 000000000047C150
Foo destroyed: 000000000047C150
Foo created: 000000000047AF90
Foo destroyed: 000000000047AF90
Foo created: 0000000000479DD0
...
하는 시점에서, 그것은 생성하고 스택 오버 플로우에 도달하고, 충돌 때까지 푸 객체를 파괴 유지합니다. 나는 다음과 같은 출력받을
Foo::~Foo()
{
std::cout << "Foo destroyed: " << this << std::endl;
if (keepThrowing_)
{
throw 1;
}
}
:
Foo created: 00000000008EF858
Foo caught
Foo destroyed: 00000000008EF858
그리고 프로그램이 디버그 주장에 도달 (나는이 조각에 소멸자를 변경하는 경우
(대신 푸의 int를 던지는) std :: terminate()가 호출되면 throw 1;
이 실행됩니다.
내 질문은 : 여기 어떻게됩니까? x64에서 MSVC가이 동작을 승인하지 않았지만 x86에서 작동하기 때문에 올바르게 작동하지 않습니다. MinGW와 MinGW-w64를 사용하여이 코드를 컴파일했고 x86과 x64 모두에 대해 두 프로그램 모두 예상대로 작동했습니다. 이것은 MSVC의 버그입니까? 누구나이 문제를 우회하는 방법을 생각해 볼 수 있습니까? 아니면 Microsoft가 x64에서이 문제를 방지하기로 결정한 이유는 무엇입니까?
감사합니다.