C 언어에는 내장된 예외 처리 지원이 없으며, 오류 처리는 다음과 같은 방법으로 구현됩니다:
오류 코드 반환 (보통 함수의 반환 값으로) 예:
int read_file(const char *name) { FILE *f = fopen(name, "r"); if (!f) return -1; // 오류 // ... fclose(f); return 0; // 성공 }
전역 변수 errno 사용
오류가 발생하면 표준 함수는 종종 전역 변수 errno를 설정합니다.
예:
FILE *fp = fopen("nofile", "r"); if (!fp) { perror("파일 오류"); // errno는 원인을 정의합니다. }
setjmp/longjmp — "예외"를 던지는 메커니즘 (실행 Context가 저장되고 복원됨) 복잡한 경우 (예: 다중 레벨 비상 종료)에 사용됩니다. 코드 복잡성을 증가시키고 자원 누수를 유발할 수 있어 드물게 사용됩니다.
#include <setjmp.h> jmp_buf buf; if (setjmp(buf) == 0) { // ... longjmp(buf, 1); // if (setjmp(...))로 이동 } else { // 오류 처리 }
다음 코드의 출력은 무엇인가요?
#include <stdio.h> #include <setjmp.h> jmp_buf buf; void func() { longjmp(buf, 5); } int main() { int val = setjmp(buf); printf("val=%d ", val); if (val == 0) func(); return 0; }
답변:
setjmp는 0을 반환하고 func 함수가 호출됩니다.longjmp(buf, 5)가 실행되고, 실행이 다시 setjmp로 돌아가는데, 이번에는 5를 반환합니다.val=0
val=5
이야기 어떤 라이브러리에서는 오류 코드에 대한 수동 자원 정리 메커니즘을 구현했지만, 프로그래머가 콜백(through setjmp/longjmp)에서 반환 시 오류 처리를 간과하여 메모리 누수 및 파일 잠금이 발생했습니다.
이야기 네트워크 애플리케이션에서 소켓 작업 후
errno체크를 놓쳤습니다. 이로 인해 이전 함수로부터의 오래된 잘못된 값이 남아 있어 잘못된 진단이 발생했습니다.
이야기 팀이 많은 오류 코드 반환 지점이 있는 복잡한 중첩 구조를 구현했지만, 반환 값(0/음수 값)에 대한 규칙을 준수하지 않았습니다. 일부 오류가 성공으로 해석되어 서비스의 예측할 수 없는 실패를 초래했습니다.