[c] 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 에는 내장 된 예외 메커니즘 이 없습니다 . 예외와 그 의미 를 시뮬레이션 해야합니다 . 이것은 일반적으로 setjmplongjmp .

주변에 꽤 많은 라이브러리가 있으며 또 다른 라이브러리를 구현하고 있습니다. 이것은 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으로 나누거나 널 포인터를 역 참조하는 기술을 공유 할 것이라고 생각했습니다.

문제는 단순히 “어떻게 던지는가”이지, 잡는 방법이나 특정 유형의 예외를 던지는 방법이 아닙니다. 나는 C ++에서 잡히기 위해 C에서 예외를 트리거해야하는 오래 전에 상황이 있었다. 특히, “순수한 가상 함수 호출”오류에 대한보고가 가끔 있었으며 C 런타임의 _purecall 함수가 무언가를 던지도록 설득해야했습니다. 그래서 우리는 0으로 나눈 우리 자신의 _purecall 함수를 추가했습니다. 그리고 boom, 우리는 C ++에서 잡을 수있는 예외를 얻었고, 어떤 일이 잘못되었는지보기 위해 스택 재미를 사용했습니다.


답변

MSVC를 사용하는 Win 에는 __try ... __except ...정말 끔찍하며 피할 수 있다면 사용하고 싶지 않습니다. 예외가 없다고 말하는 것이 좋습니다.