programing

어떻게 하면 C에 예외를 둘 수 있나요?

copysource 2022. 7. 16. 13:39
반응형

어떻게 하면 C에 예외를 둘 수 있나요?

구글에 입력했는데 사용법만 C++로 입력했어요.

어떻게 하면 C로 할 수 있죠?

C에는 예외가 없습니다.C에서는 반환된 함수의 값, 프로세스의 종료 값, 프로세스에 대한 신호(Program Error Signals(GNU libc; 프로그램오류 신호) 또는 CPU 하드웨어 중단(또는 CPU가 있는 경우 CPU에서 발생하는 기타 알림 오류)에 의해 에러가 통지된다(프로세서가 0으로 분할된 경우를 처리하는 방법).

예외는 C++ 및 기타 언어로 정의되어 있습니다.C++에서의 예외 처리는 C++ 표준 "S.15 예외 처리"에 명시되어 있으며, C 표준에는 동등한 섹션이 없다.

에서는 C와 C를 할 수 .setjmp() ★★★★★★★★★★★★★★★★★」longjmp()에되어 있습니다.setjmp.hWikipedia의 예

#include <stdio.h>
#include <setjmp.h>

static jmp_buf buf;

void second(void) {
    printf("second\n");         // prints
    longjmp(buf,1);             // jumps back to where setjmp 
                                //   was called - making setjmp now return 1
}

void first(void) {
    second();
    printf("first\n");          // does not print
}

int main() {   
    if ( ! setjmp(buf) ) {
        first();                // when executed, setjmp returns 0
    } else {                    // when longjmp jumps back, setjmp returns 1
        printf("main");         // prints
    }

    return 0;
}

주의: C++(로컬 오브젝트의 파괴자는 불리지 않는다)로 동작하기 때문에, 실제로는 사용하지 않는 것을 추천합니다.대신 어떤 종류의 오류를 반환하십시오.

C는 C++ 예외를 발생시킬 수 있습니다.어쨌든 기계코드입니다.

를 들어 file bar.c:

#include <stdlib.h>
#include <stdint.h>

extern void *__cxa_allocate_exception(size_t thrown_size);
extern void __cxa_throw (void *thrown_exception, void* *tinfo, void (*dest) (void *) );
extern void * _ZTIl; // typeinfo of long

int bar1()
{
   int64_t * p = (int64_t*)__cxa_allocate_exception(8);
   *p = 1976;
   __cxa_throw(p, &_ZTIl, 0);
  return 10;
}

파일 a.cc에서

#include <stdint.h>
#include <cstdio>
extern "C" int bar1();

void foo()
{
  try
  {
    bar1();
  }
  catch(int64_t x)
  {
    printf("good %ld", x);
  }
}

int main(int argc, char *argv[])
{
  foo();
  return 0;
}

컴파일 방법:

gcc -o bar.o -c bar.c && g++ a.cc bar.o && ./a.out

산출량

good 1976

https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html 에 대한 자세한 정보가 있습니다.__cxa_throw.

휴대성이 좋은지 어떤지는 잘 모르겠고 Linux에서 'gcc-4.8.2'로 테스트합니다.

C에는 예외 메커니즘이 내장되어 있지 않습니다.예외와 그 의미를 시뮬레이션해야 합니다.이것은 보통 다음 항목에 의존함으로써 달성된다.setjmp ★★★★★★★★★★★★★★★★★」longjmp.

주변에는 꽤 많은 도서관이 있고, 저는 또 다른 도서관을 구현하고 있습니다.Exceptions4c라고 합니다.휴대용으로 무료입니다.어떤 것이 가장 적합한지 살펴보고 다른 대안과 비교해 보십시오.

이 질문은 아주 오래된 질문입니다만, 우연히 알게 된 후, 기술을 공유하려고 합니다: 0으로 나누거나, 늘 포인터를 참조 해제하거나.

문제는 단순히 "어떻게 던질 것인가"이지, 잡는 방법이나 특정 유형의 예외를 어떻게 던질 것인가 하는 것이 아닙니다.몇 년 전에 C++에서 검출하기 위해 C에서 예외를 트리거해야 하는 상황이 있었습니다.특히, "순수한 가상 함수 호출" 오류에 대한 보고가 가끔 있었고, C 런타임의 _purecall 함수를 설득하여 무언가를 던질 필요가 있었습니다.그래서 우리는 0으로 나누어진 자체 _purecall 함수를 추가했고, C++에서 잡을 수 있는 예외를 얻었고, 심지어 스택의 재미로 문제가 발생한 부분을 확인할 수 있었습니다.

Microsoft Visual C++(MSVC)를 탑재한 Windows에서는__try ... __except ...하지만 정말 끔찍하고 피할 수 있다면 쓰고 싶지 않을 거예요.예외는 없다고 말하는 편이 낫다.

플레인 올드 C는 실제로 예외를 네이티브하게 지원하지 않습니다.

다음과 같은 대체 오류 처리 전략을 사용할 수 있습니다.

  • 에러 코드 반환
  • 돌아오는FALSE및 를 사용하여last_error변수 또는 함수.

http://en.wikibooks.org/wiki/C_Programming/Error_handling 를 참조해 주세요.

Eric Roberts에 의한 C의 예외 구현.

Hanson의 C 인터페이스구현 4장

Doug Moen의 오류 처리 방법

C의 예외 구현(E. Roberts 기사 상세)

해피패스 설계 패턴(예를 들어 임베디드 디바이스의 경우)을 사용하여 코드를 작성하는 경우 연산자 goto를 사용하여 예외 오류 처리(AKA 디퍼링 또는 최종 에뮬레이션)를 시뮬레이션할 수 있습니다.

int process(int port)
{
    int rc;
    int fd1;
    int fd2;

    fd1 = open("/dev/...", ...);
    if (fd1 == -1) {
      rc = -1;
      goto out;
    }

    fd2 = open("/dev/...", ...);
    if (fd2 == -1) {
      rc = -1;
      goto out;
    }

    // Do some with fd1 and fd2 for example write(f2, read(fd1))

    rc = 0;

   out:

    //if (rc != 0) {
        (void)close(fd1);
        (void)close(fd2);
    //}

    return rc;
}

실제로는 예외 핸들러는 아니지만 함수 종료 시 오류를 처리할 수 있습니다.

추신: goto는 동일하거나 그 이상의 딥 스코프에서만 사용하고 변수 선언을 점프하지 않도록 주의해야 합니다.

C는 예외를 지원하지 않습니다.C 코드를 Visual Studio 또는 G++에서 C++로 컴파일하여 그대로 컴파일 할 수 있는지 확인할 수 있습니다.대부분의 C 어플리케이션은 큰 변경 없이 C++로 컴파일 됩니다.그러면 try를 사용할 수 있습니다.catch 구문

C에는 예외가 없습니다.

이를 시도하는 다양한 해킹 구현이 있습니다(예: http://adomas.org/excc/)).

많은 스레드에서 설명한 바와 같이 이를 위한 "표준" 방법은 setjmp/longjmp를 사용하는 것입니다.또 다른 솔루션을 https://github.com/psevon/exceptions-and-raii-in-c에 올렸습니다.제가 아는 바로는 이 솔루션만이 할당된 자원의 자동 청소에 의존하고 있습니다.고유한 공유 스마트포인터를 구현하여 중간 함수가 예외를 포착하지 않고 통과시키고 로컬로 할당된 리소스를 적절하게 정리할 수 있습니다.

C에서는 try case를 사용하여 오류를 처리할 수 없지만 Windows.h를 사용하여 다음을 수행할 수 있습니다.

#include <stdio.h>
#include <Windows.h>
#include <setjmp.h>
jmp_buf Buf;

NTAPI Error_Handler(struct _EXCEPTION_POINTERS *ExceptionInfo)
{
    printf("co loi roi ban oi.!!!\r\n");
    longjmp(Buf, 1);
}

void main()
{
    AddVectoredExceptionHandler(1, Error_Handler);
    int x = 0;
    printf("start main\r\n");
    if (setjmp(Buf) == 0)
    {
        int y = 1 / x;
    }
    printf("end main\r\n");
    
}

언급URL : https://stackoverflow.com/questions/2891766/how-can-i-throw-an-exception-in-c

반응형