문제

C ++ 예외 처리 메커니즘의 작동 방식에 흥미가 있습니다. 구체적으로, 예외 객체는 어디에 저장되었으며, 잡히기 전까지 몇 가지 스코프를 통해 어떻게 전파됩니까? 일부 전 세계 지역에 저장되어 있습니까?

이것은 컴파일러에 따라 G ++ 컴파일러 제품군의 맥락에서 이것을 설명 할 수 있습니까?

도움이 되었습니까?

해결책

구현은 다를 수 있지만 요구 사항에서 따르는 몇 가지 기본 아이디어가 있습니다.

예외 객체 자체는 한 기능으로 생성 된 객체이며 발신자에서 파괴되었습니다. 따라서 일반적으로 스택에 객체를 만드는 것은 가능하지 않습니다. 반면에, 많은 예외 객체는 그리 크지 않습니다. Ergo, 예를 들어 32 바이트 버퍼를 만들 수 있으며 더 큰 예외 객체가 실제로 필요한 경우 힙으로 넘쳐납니다.

실제 통제 전달에 관해서는 두 가지 전략이 존재합니다. 하나는 스택을 풀기 위해 충분한 정보를 스택 자체에 녹음하는 것입니다. 이것은 기본적으로 실행할 소멸자 목록과 예외를 포착 할 수있는 예외 처리기입니다. 예외가 발생하면 어울리는 캐치를 찾을 때까지 해당 소멸자 실행 스택을 다시 실행하십시오.

두 번째 전략은이 정보를 스택 외부 테이블로 옮깁니다. 이제 예외가 발생하면 통화 스택은 어떤 스코프가 입력되었지만 종료되지 않은지 알아내는 데 사용됩니다. 그런 다음 정적 테이블에서 찾아 보면서 제외 된 예외가 어디에서 처리 될지, 그리고 어떤 소멸자가 그 사이에 실행되는지를 결정합니다. 이것은 스택에 예외 오버 헤드가 적다는 것을 의미합니다. 어쨌든 반환 주소가 필요합니다. 테이블은 추가 데이터이지만 컴파일러는 프로그램의 수요로드 된 세그먼트에 넣을 수 있습니다.

다른 팁

이것은 표준을 제외하고 15.1로 정의됩니다.

던지기는 임시 객체를 만듭니다.
이 임시 객체에 대한 메모리가 할당되는 방법은 지정되지 않습니다.

임시 객체 컨트롤을 작성한 후 통화 스택에서 가장 가까운 핸들러로 전달됩니다. 던지기와 캐치 포인트 사이에 스택을 풀기. 스택이 풀리면 모든 스택 변수는 반대 순서로 파괴됩니다.

예외가 재투자되지 않는 한, 핸들러가 잡힌 곳에서 임시는 파괴됩니다.

참고 : 참조별로 참조하면 참조가 임시를 참조하면 값으로 캐치하면 임시 객체가 값으로 복사되므로 카피 생성자가 필요합니다).

S.Meyers의 조언 (Const 참조).

try
{
    // do stuff
}
catch(MyException const& x)
{
}
catch(std::exception const& x)
{
}

당신은 볼 수 있습니다 여기 자세한 설명을 위해.

또한 기본적인 종류의 예외 처리를 구현하기 위해 Plain C에 사용 된 트릭을 살펴 보는 데 도움이 될 수 있습니다. 여기에는 다음과 같은 방식으로 setjmp () 및 longjmp ()를 사용하여 전자가 스택을 저장하여 예외 핸들러를 표시하기 위해 스택을 저장하는 반면 (예 : "Catch")는 값을 "던지는 데"사용됩니다. "Thrown"값은 마치 호출 된 함수에서 반환 된 것처럼 보입니다. SetJmp ()가 다시 호출되거나 함수가 돌아올 때 "시도 된 블록"이 종료됩니다.

나는 이것이 오래된 질문이라는 것을 알고 있지만, 각 GCC와 VC에 사용 된 방법을 모두 설명하는 매우 좋은 설명이 있습니다. http://www.hexblog.com/wp-content/uploads/2012/06/recon-2012-skochinsky-compiler-internals.pdf

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