어떻게 하면 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.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++(로컬 오브젝트의 파괴자는 불리지 않는다)로 동작하기 때문에, 실제로는 사용하지 않는 것을 추천합니다.대신 어떤 종류의 오류를 반환하십시오.
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 를 참조해 주세요.
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
'programing' 카테고리의 다른 글
0으로 나눗셈을 하지 않은 것은 정의되지 않은 동작입니까? (0) | 2022.07.16 |
---|---|
vuex 상태에 액세스하는 데 어려움을 겪고 있습니다. (0) | 2022.07.16 |
세트에서 랜덤 요소 선택 (0) | 2022.07.16 |
pthreads의 조건 변수 함수에 뮤텍스가 필요한 이유는 무엇입니까? (0) | 2022.07.16 |
C/C++에서 서명된 오버플로를 감지하는 중 (0) | 2022.07.16 |