IT TIP

C ++ 예외 처리 런타임은 어떻게 구현됩니까?

itqueen 2020. 10. 12. 21:19
반응형

C ++ 예외 처리 런타임은 어떻게 구현됩니까?


C ++ 예외 처리 메커니즘이 작동하는 방식에 흥미가 있습니다. 특히 예외 개체는 어디에 저장되며 포착 될 때까지 여러 범위를 통해 어떻게 전파됩니까? 일부 글로벌 영역에 저장됩니까?

이것이 컴파일러 특정 일 수 있기 때문에 누군가 g ++ 컴파일러 스위트의 맥락에서 이것을 설명 할 수 있습니까?


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

예외 객체 자체는 하나의 함수에서 생성되고 호출자에서 파괴 된 객체입니다. 따라서 일반적으로 스택에 개체를 만드는 것은 불가능합니다. 반면에 많은 예외 객체는 그다지 크지 않습니다. 예를 들어 32 바이트 버퍼를 생성하고 더 큰 예외 객체가 실제로 필요한 경우 힙으로 오버플로 할 수 있습니다.

실제 통제권 이전에는 두 가지 전략이 있습니다. 하나는 스택 자체에 충분한 정보를 기록하여 스택을 푸는 것입니다. 이것은 기본적으로 실행할 소멸자 목록과 예외를 포착 할 수있는 예외 처리기입니다. 예외가 발생하면 일치하는 catch를 찾을 때까지 해당 소멸자를 실행하는 스택을 다시 실행하십시오.

두 번째 전략은이 정보를 스택 외부의 테이블로 이동합니다. 이제 예외가 발생하면 호출 스택을 사용하여 입력되었지만 종료되지 않은 범위를 찾습니다. 그런 다음 정적 테이블에서 조회하여 throw 된 예외가 처리 될 위치와 그 사이에서 실행되는 소멸자를 결정합니다. 이는 스택에 대한 예외 오버 헤드가 적다는 것을 의미합니다. 어쨌든 반환 주소가 필요합니다. 테이블은 추가 데이터이지만 컴파일러는 프로그램의 요구로드 세그먼트에 테이블을 넣을 수 있습니다.


이것은 15.1 표준 예외 던지기에 정의되어 있습니다.

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

임시 개체 컨트롤을 만든 후 호출 스택에서 가장 가까운 처리기로 전달됩니다. 던지기와 잡기 지점 사이의 스택 풀기. 스택이 풀리면 스택 변수는 생성의 역순으로 파괴됩니다.

예외가 다시 발생하지 않는 한 임시는 포착 된 핸들러의 끝에서 파기됩니다.

참고 : 참조로 catch하는 경우 참조는 임시를 참조하고 값으로 catch하면 임시 개체가 값에 복사되므로 복사 생성자가 필요합니다.

S.Meyers의 조언 (const 참조로 잡기).

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

자세한 설명 여기 를 참조 하십시오 .

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


나는 이것이 오래된 질문이라는 것을 알고 있지만 gcc와 VC 각각에서 사용되는 방법을 모두 설명하는 매우 좋은 설명이 있습니다. http://www.hexblog.com/wp-content/uploads/2012/06/Recon- 2012-Skochinsky-Compiler-Internals.pdf

참고 URL : https://stackoverflow.com/questions/490773/how-is-the-c-exception-handling-runtime-implemented

반응형