유효하지 않은 에러 코드
유효하지 않은 에러 코드
어떤 정수 값을 에러로 바꾸려고 할 때, 그 값이 실제로 어떤 에러도 나타내지 않는다면 컴파일 타임과 런타임에서 각각 다른 방식으로 실패하게 돼요. 이 섹션에서는 @errorFromInt가 이런 상황에서 어떻게 동작하는지 두 경우로 나눠 살펴볼게요.
본문
컴파일 타임에는 이렇게 써볼 수 있어요. @errorFromInt에 에러를 표현하지 않는 정수를 넘기면 컴파일러가 바로 잡아내죠.
comptime {
_ = @errorFromInt(12345);
}
$ zig test test_comptime_invalid_error_code.zig
/home/ci/work/zig-bootstrap/zig/doc/langref/test_comptime_invalid_error_code.zig:2:23: error: integer value '12345' represents no error
_ = @errorFromInt(12345);
^~~~~
12345는 어떤 에러 값에도 해당하지 않아요. 그래서 이건 no error를 의미하는 정수라는 에러 메시지가 나오면서 컴파일이 실패하는 걸 볼 수 있어요.
런타임에는 값을 예측할 수 없을 때가 있죠. 아래처럼 에러에서 정수로 바꾼 뒤 500을 더해, 실제로 존재하지 않는 에러 코드를 만들어볼게요.
const std = @import("std");
pub fn main() void {
const err = error.AnError;
var number = @intFromError(err) + 500;
_ = &number;
const invalid_err = @errorFromInt(number);
std.debug.print("value: {}\n", .{invalid_err});
}
$ zig build-exe runtime_invalid_error_code.zig
$ ./runtime_invalid_error_code
thread 972966 panic: invalid error code
/home/ci/work/zig-bootstrap/zig/doc/langref/runtime_invalid_error_code.zig:7:5: 0x11e82c5 in main (runtime_invalid_error_code.zig)
const invalid_err = @errorFromInt(number);
^
/home/ci/work/zig-bootstrap/out/host/lib/zig/std/start.zig:788:64: 0x11e7bbb in callMain (std.zig)
if (fn_info.param_types.len == 0) return wrapMain(root.main());
^
/home/ci/work/zig-bootstrap/out/host/lib/zig/std/start.zig:248:5: 0x11e75e1 in _start (std.zig)
asm volatile (switch (native_arch) {
^
(process terminated by signal)
이번에는 컴파일러가 잡아주지 않아요. number가 런타임에 계산되는 값이라 컴파일러가 미리 알 수 없거든요. 실행하면 panic: invalid error code가 나오면서 프로그램이 죽는 걸 확인할 수 있어요.
더 알아보기
@errorFromInt/@intFromError— 정수와 에러 값을 서로 변환하는 내장 함수- 에러 값과 에러 유니온의 전반적인 동작은 Zig 문서의 Errors 섹션에서 다뤄져요.