programing

C에서 예외를 던지는 방법은 무엇입니까?

nasanasas 2020. 9. 16. 07:46
반응형

C에서 예외를 던지는 방법은 무엇입니까?


나는 이것을 구글에 입력했지만 C ++에서만 howtos를 찾았습니다.

C로하는 방법?


C에는 예외가 없습니다. C에서는 함수의 반환 값, 프로세스의 종료 값, 프로세스에 대한 신호 ( 프로그램 오류 신호 (GNU libc) ) 또는 CPU 하드웨어 중단 (또는 기타 알림 오류)을 통해 오류를 알립니다. 있는 경우 CPU를 형성) ( 프로세서가 0으로 나눈 경우를 처리하는 방법 ).

그러나 C ++ 및 다른 언어로 정의 된 예외. C ++의 예외 처리는 C ++ 표준 "S.15 예외 처리"에 지정되어 있으며 C 표준에는 해당 섹션이 없습니다.


C에서는 에 정의 된 setjmp()longjmp()함수 의 조합을 사용할 수 있습니다 setjmp.h. Wikipedia의 예

#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 ++ (로컬 객체의 소멸자가 호출되지 않음)로 작동하기 때문에 사용 하지 말라고 조언 하고 무슨 일이 일어나고 있는지 이해하기가 정말 어렵습니다. 대신 어떤 종류의 오류를 반환하십시오.


Plain old C는 실제로 기본적으로 예외를 지원하지 않습니다.

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

  • 오류 코드 반환
  • 변수 또는 함수 반환 FALSE및 사용 last_error.

http://en.wikibooks.org/wiki/C_Programming/Error_handling을 참조하십시오 .


C 에는 내장 된 예외 메커니즘 이 없습니다 . 예외와 그 의미 시뮬레이션 해야합니다 . 이는 일반적으로 setjmp에 의존하여 수행됩니다 longjmp.

주변에 꽤 많은 라이브러리가 있으며 또 다른 라이브러리를 구현하고 있습니다. 이것은 exceptions4c 라고합니다 . 휴대 가능하고 무료입니다. 그것을 살펴보고 다른 대안 과 비교하여 가장 적합한 것을 확인할 수 있습니다.


C는 C ++ 예외를 던질 수 있지만 어쨌든 기계 코드입니다. 예를 들어, bar.c에서

// begin 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;
}
// end bar.c

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

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

나는 그것이 이식 가능한지 아닌지 확실하지 않으며 Linux에서 'gcc-4.8.2'로 테스트합니다.


이 질문은 매우 오래되었지만 방금 우연히 발견하여 0으로 나누거나 널 포인터를 역 참조하는 기술을 공유 할 것이라고 생각했습니다.

The question is simply "how to throw", not how to catch, or even how to throw a specific type of exception. I had a situation ages ago where we needed to trigger an exception from C to be caught in C++. Specifically, we had occasional reports of "pure virtual function call" errors, and needed to convince the C runtime's _purecall function to throw something. So we added our own _purecall function that divided by zero, and boom, we got an exception that we could catch on C++, and even use some stack fun to see where things went wrong.


On Win with MSVC there's __try ... __except ... but it's really horrible and you don't want to use it if you can possibly avoid it. Better to say that there are no exceptions.


C doesn't have exceptions.

There are various hacky implementations that try to do it (one example at: http://adomas.org/excc/).


As mentioned in numerous threads, the "standard" way of doing this is using setjmp/longjmp. I posted yet another such solution to https://github.com/psevon/exceptions-and-raii-in-c This is to my knowledge the only solution that relies on automatic cleanup of allocated resources. It implements unique and shared smartpointers, and allows intermediate functions to let exceptions pass through without catching and still have their locally allocated resources cleaned up properly.


C doesn't support exceptions. You can try compiling your C code as C++ with Visual Studio or G++ and see if it'll compile as-is. Most C applications will compile as C++ without major changes, and you can then use the try... catch syntax.


If you write code with Happy path design pattern (i.e. for embedded device) you may simulate exception error processing (aka deffering or finally emulation) with operator "goto".

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;
}

It does not actually exception handler but it take you a way to handle error at fucntion exit.

P.S. You should be careful use goto only from same or more deep scopes and never jump variable declaration.

참고URL : https://stackoverflow.com/questions/2891766/how-to-throw-an-exception-in-c

반응형