@compileError — 컴파일 에러 만들기

@compileError — 컴파일 에러 만들기

프로그램을 짜다 보면, **'지금 이 상태의 코드는 아예 컴파일이 되면 안 된다'**고 알려줘야 할 때가 있어요. Zig에는 그러한 상황을 명시적으로 드러내는 내장 함수가 있는데, 그게 바로 @compileError예요. 이 함수를 만나면 컴파일러가 그 즉시 에러로 멈춰주죠. 이번 섹션에서는 @compileError가 무엇이고, 언제, 어떻게 쓰는지 살펴볼게요.

출처: Zig Documentation

본문

@compileError의 형태는 이렇게 생겼어요.

@compileError(comptime msg: []const u8) noreturn

이 함수는 의미 분석(semantic analysis) 단계에서 평가되는 순간, 전달받은 msg를 메시지로 하는 컴파일 에러를 일으켜요. 즉 코드가 실제로 실행되기 전에, 컴파일러가 이 지점을 분석하면서 멈추는 거죠.

그런데 잠깐, "항상 컴파일 에러가 나는 함수를 왜 쓰지?" 하고 의문이 들 수 있어요. 답은 이 함수가 항상 평가되지는 않는다는 데 있어요. Zig에서는 특정 조건에서만 코드가 의미 분석을 거치게 만들 수 있고, 그 '조건에 걸린 경우에만' 에러를 내는 방식으로 쓰이거든요.

의미 분석을 건너뛰게 만드는 대표적인 방법은 몇 가지가 있어요.

  • comptime 상수와 함께 ifswitch를 사용하는 경우 — 컴파일 타임에 이미 분기가 정해지면, 실행되지 않는 쪽은 분석되지 않아요.
  • comptime 함수를 사용하는 경우 — 컴파일 타임에 호출되는 함수 안에서만 @compileError에 도달한다면, 그 경로가 실제로 실행될 때만 에러가 나죠.

덕분에 @compileError는 "이 코드 경로는 존재해서는 안 되고, 만약 컴파일 타임에 여기까지 오면 반드시 실패해야 한다"는 불변 조건을 컴파일러에게 확실히 각인시키는 도구로 아주 유용해요. 예를 들어 타입에 따라 지원되지 않는 조합을 컴파일 타임에 잡아내고 싶을 때 switch의 특정 가지에 @compileError를 두는 식으로 자주 활용해요.

더 알아보기

  • Zig Documentation — 이 문서의 전체 목차와 기능별 상세 설명
  • @compileLog — 다음 섹션에서 다루는, 컴파일 타임에 값을 출력해 주는 @compileLog 설명