기본 패턴
c
#include <assert.h>
#include <errno.h>
#include <stdio.h>
// assert — 조건이 거짓이면 즉시 abort
assert(ptr != NULL);
// errno — 표준 라이브러리 함수 실패 후 오류 코드 확인
FILE *fp = fopen("no_file.txt", "r");
if (!fp) {
perror("fopen"); // "fopen: No such file or directory"
}설명
assert — 개발 중 불변식 검사
c
#include <assert.h>
int divide(int a, int b) {
assert(b != 0); // 조건이 0이면: 파일명, 줄 번호와 함께 abort
return a / b;
}
// NDEBUG 매크로가 정의되면 assert는 완전히 제거됨
// 릴리스 빌드: gcc -DNDEBUG file.c
// → assert는 런타임 비용 0
// 정적 어서션 (컴파일 타임 검사, C11)
_Static_assert(sizeof(int) == 4, "int는 4바이트여야 합니다");errno — 표준 라이브러리 오류 코드
많은 표준 함수는 실패 시 전역 변수 errno에 오류 코드를 기록합니다.
c
#include <errno.h>
#include <string.h> // strerror
// errno는 성공 시에도 변경될 수 있으므로
// 실패를 확인한 직후 errno를 읽어야 함
errno = 0; // 선택적으로 먼저 초기화
FILE *fp = fopen("missing.txt", "r");
if (!fp) {
int saved = errno; // 즉시 저장
fprintf(stderr, "오류 코드: %d\n", saved);
fprintf(stderr, "오류 메시지: %s\n", strerror(saved));
}perror — errno 기반 메시지 출력
c
// perror("prefix") → "prefix: errno 메시지\n"
FILE *fp = fopen("data.txt", "r");
if (!fp) {
perror("파일 열기 실패");
// 예: "파일 열기 실패: No such file or directory"
return 1;
}
// strerror — 오류 코드를 문자열로 반환 (perror 대신 직접 포맷할 때)
fprintf(stderr, "[%d] %s\n", errno, strerror(errno));자주 보이는 errno 값
c
#include <errno.h>
ENOENT // 2 — 파일/디렉토리 없음
EACCES // 13 — 권한 없음
EINVAL // 22 — 잘못된 인수
ENOMEM // 12 — 메모리 부족
EEXIST // 17 — 이미 존재
ENOBUFS // 이식성 없음, POSIX 한정빠른 정리
| 항목 | 역할 |
|---|---|
assert(expr) | expr이 거짓이면 abort + 오류 위치 출력 |
NDEBUG | 정의 시 assert 완전 비활성화 (릴리스 빌드) |
_Static_assert(expr, msg) | 컴파일 타임 조건 검사 (C11) |
errno | 표준 라이브러리 함수 실패 후 오류 코드 |
perror(prefix) | errno 기반 오류 메시지를 stderr에 출력 |
strerror(n) | 오류 코드 n을 설명 문자열로 변환 |
주의할 점
assert는 런타임 오류 처리가 아닌 개발 중 불변식 검사용입니다. 사용자 입력 검증이나 프로덕션 오류 처리에는 사용하지 마세요. 릴리스 빌드에서 NDEBUG로 제거되면 그 안의 부작용 코드도 함께 사라집니다.
errno는 성공한 함수 호출 후에도 값이 바뀔 수 있습니다. 실패를 확인한 직후 즉시 읽어야 정확한 오류를 알 수 있습니다.
참고 링크
2 sources