프로그래밍백엔드 C 개발자

C 표준 라이브러리 함수 작업 중 오류 처리를 어떻게 구현합니까? errno 사용의 특성은 무엇이며, 반환 코드를 언제 사용하는 것이 좋으며, 오류 처리를 할 때 실수를 피하려면 어떻게 해야 합니까?

Hintsage AI 어시스턴트로 면접 통과

답변.

질문의 역사

C 언어에서 오류 처리는 항상 개발자의 과제였습니다. 표준 라이브러리에는 예외가 없으며, 오류는 반환 코드 또는 글로벌 변수 errno를 통해 반환됩니다(사용 시작 — 1970년대 UNIX, 이후 POSIX 및 ANSI C). 이러한 메커니즘은 오늘날에도 비정상적인 상황에서 흐름 제어를 위해 사용됩니다.

문제

표준 함수(파일 작업, 메모리 할당, 문자열 함수)를 사용할 때 오류는 특별한 제어 없이는 감지되지 않을 수 있습니다. 잘못된 처리 — 반환 코드 무시, errno 해석 오류, 리소스 정리 부족 — 는 프로그램의 잘못된 동작, 충돌 및 취약점으로 이어질 수 있습니다.

해결책

올바른 오류 처리는 반드시 함수가 반환하는 값을 분석하고, 실패 직후에만 errno를 사용하며, 오류에 대한 정보 제공이 필요합니다. 반환 코드는 내부 함수에 선호되며, 글로벌 부작용 없이 처리를 가능하게 합니다. errno는 시스템 호출 및 표준 라이브러리 함수와 함께 더 자주 사용됩니다. 각 잠재적으로 위험한 작업 후에 반환 값을 분석하고, 글로벌 상태(errno)는 중간 호출로 덮어써지지 않아야 합니다.

코드 예:

#include <stdio.h> #include <errno.h> #include <string.h> FILE *open_file(const char *filename) { errno = 0; FILE *f = fopen(filename, "r"); if (!f) { fprintf(stderr, "오류: %s ", strerror(errno)); } return f; }

주요 특징:

  • errno는 시스템 호출/표준 함수에서 발생한 오류 진단에만 사용됩니다.
  • 함수 내에서 int 오류 코드를 반환하는 것이 편리하며, 0은 성공, 음수 또는 특수 값은 실패를 나타냅니다.
  • 오류가 없었던 경우에는 errno 값에 의존하지 않는 것이 중요합니다.

함정 질문.

사용자 정의 함수에서 오류를 위로 전달하려면 errno를 사용할 수 있습니까?

아니요, errno는 표준 라이브러리 및 시스템 호출에만 사용되도록 설계되었습니다. 그것은 전역적이며 어떤 시점에서든 덮어쓸 수 있으므로 자체 함수에는 적합하지 않습니다.

각 함수 호출 전에 errno를 설정해야 합니까?

아니요, 그러나 변경 사항을 분석할 계획이라면 호출 전에 errno(예: 0으로) 초기화하는 것이 좋습니다. 모든 함수가 성공 시 errno를 변경하는 것은 아니며 오류 시에만 변경합니다.

eno = 0; ... 위험한 함수 호출 ...

모든 함수 호출 후 errno를 신뢰할 수 있습니까?

오류 발생 시 명시적으로 설정한다고 표준이 정하고 있는 함수에 대해서만 가능합니다. 많은 표준 라이브러리 함수는 성공 시 errno를 변경하지 않습니다. 문서가 당신의 친구입니다.

일반적인 오류 및 안티 패턴

  • 함수의 반환 코드 무시 (예: fopen, malloc, write).
  • 값을 사용하기 전에 errno를 덮어쓰기.
  • 프로젝트에서 자신의 오류에 대해 errno 사용.

실생활 사례

부정적인 사례

결과를 확인하지 않고 파일을 열고, 오류가 분석되지 않으며, 파일이 없을 때 프로그램이 잘못 작동합니다:

장점:

  • 코드가 적어서 간단한 시나리오에서 빠르게 작동합니다.

단점:

  • 오류가 발생했을 때 모호한 실패, 진단 불가능.

긍정적인 사례

모든 중요한 함수 후에 결과를 확인하고, 오류 발생 시 strerror(errno)로 상세한 메시지를 출력하며, 올바르게 실행을 종료합니다:

장점:

  • 프로그램 유지 보수 및 디버그가 용이하며 높은 안정성을 가집니다.

단점:

  • 코드가 약간 더 많고 약간의 복잡성이 증가합니다.