나는 이것을 구글에 입력했지만 C ++에서만 howtos를 찾았습니다.
C로하는 방법?
나는 이것을 구글에 입력했지만 C ++에서만 howtos를 찾았습니다.
C로하는 방법?
답변:
C에는 예외가 없습니다. C에서 오류는 함수의 반환 된 값, 프로세스의 종료 값, 프로세스에 대한 신호 ( 프로그램 오류 신호 (GNU libc) ) 또는 CPU 하드웨어 중단 (또는 기타 알림 오류가있는 경우 CPU에서 오류) ( 프로세서가 0으로 나누는 경우를 처리하는 방법 ).
예외는 C ++ 및 기타 언어로 정의됩니다. C ++의 예외 처리는 C ++ 표준 "S.15 예외 처리"에 지정되어 있으며 C 표준에는 해당 섹션이 없습니다.
main
A의 .c
자주 C로 작성 기능에 의존하는 파일은 일부 C ++를 포함 할 수 있으므로 예외가 발생하고 프로그램에서 잡은 있지만, C 코드 부분이 그 예외 던지기를 제외하고가는이 모든 무지 남아 잡는 수 C ++ 라이브러리에 있습니다. C는 throw
예외 자체를 던질 필요가 있도록 호출 된 함수가 위험 할 수 없기 때문에 사용 됩니다. 하지만 예외를 throw / catch하는 컴파일러 / 라이브러리 / 타겟 특정 방법이있을 수 있습니다. 그러나 클래스 인스턴스를 던지는 것은 나름대로 문제가 있습니다.
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 ++ (로컬 객체의 소멸자가 호출되지 않음)로 작동하므로 사용 하지 않는 것이 좋으며 무슨 일이 일어나고 있는지 이해하기가 정말 어렵습니다. 대신 어떤 종류의 오류를 반환하십시오.
if()
. 나는 그 안에있는 위험을 볼 수 없습니다. 여기 다른 사람이 있습니까?
Plain old C는 실제로 기본적으로 예외를 지원하지 않습니다.
다음과 같은 대체 오류 처리 전략을 사용할 수 있습니다.
FALSE
및 사용 last_error
.http://en.wikibooks.org/wiki/C_Programming/Error_handling을 참조하십시오 .
GetLastError()
Windows API에서.
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'로 테스트합니다.
_ZTII
의미 typeinfo for long
, 예 echo '_ZTIl' | c++filt
. g ++ 맹 글링 방식입니다.
이 질문은 매우 오래되었지만 방금 우연히 발견하여 0으로 나누거나 널 포인터를 역 참조하는 기술을 공유 할 것이라고 생각했습니다.
문제는 단순히 "어떻게 던지는가"이지, 잡는 방법이나 특정 유형의 예외를 던지는 방법이 아닙니다. 나는 C ++에서 잡히기 위해 C에서 예외를 트리거해야하는 오래 전에 상황이 있었다. 특히, "순수한 가상 함수 호출"오류에 대한보고가 가끔 있었으며 C 런타임의 _purecall 함수가 무언가를 던지도록 설득해야했습니다. 그래서 우리는 0으로 나눈 우리 자신의 _purecall 함수를 추가했습니다. 그리고 boom, 우리는 C ++에서 잡을 수있는 예외를 얻었고, 어떤 일이 잘못되었는지보기 위해 스택 재미를 사용했습니다.
MSVC를 사용하는 Win 에는 __try ... __except ...
정말 끔찍하며 피할 수 있다면 사용하고 싶지 않습니다. 예외가 없다고 말하는 것이 좋습니다.
C에는 예외가 없습니다.
이를 시도하는 다양한 해키 구현이 있습니다 (예 : http://adomas.org/excc/ ).
여러 스레드에서 언급했듯이이를 수행하는 "표준"방법은 setjmp / longjmp를 사용하는 것입니다. https://github.com/psevon/exceptions-and-raii-in-c에 또 다른 솔루션을 게시했습니다. 이것은 할당 된 리소스의 자동 정리에 의존하는 유일한 솔루션입니다. 고유하고 공유 된 스마트 포인터를 구현하고 중간 함수가 예외를 포착하지 않고 통과하도록 허용하고 로컬에서 할당 된 리소스를 적절하게 정리할 수 있습니다.
C는 예외를 지원하지 않습니다. Visual Studio 또는 G ++를 사용하여 C 코드를 C ++로 컴파일하고있는 그대로 컴파일되는지 확인할 수 있습니다. 대부분의 C 응용 프로그램은 큰 변경없이 C ++로 컴파일되므로 try ... catch 구문을 사용할 수 있습니다.
해피 경로 디자인 패턴 (예 : 임베디드 장치 용)으로 코드를 작성하면 "goto"연산자를 사용하여 예외 오류 처리 (일명 deffering 또는 최종 에뮬레이션)를 시뮬레이션 할 수 있습니다.
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를 사용하고 변수 선언을 점프하지 마십시오.