0으로 나누기
0으로 나누기
0으로 나누기는 Zig에서 절대 허용되지 않아요. 컴파일 타임이든 런타임이든, 프로그래머의 실수를 그대로 두지 않고 확실하게 잡아주는 게 Zig의 철학이죠.
본문
0으로 나누기는 굉장히 위험한 연산이라서, Zig는 이 상황을 정적(컴파일 타임)이든 동적(런타임)이든 둘 다 가만히 두지 않아요.
컴파일 타임에는 컴파일러가 0으로 나누는 코드를 발견하는 순간 그 자리에서 오류를 냅니다. 상수끼리 나누는 아래 코드는 컴파일하는 동안 이미 걸려요.
comptime {
const a: i32 = 1;
const b: i32 = 0;
const c = a / b;
_ = c;
}
Shell:
$ zig test test_comptime_division_by_zero.zig
/home/ci/work/zig-bootstrap/zig/doc/langref/test_comptime_division_by_zero.zig:4:19: error: division by zero here causes illegal behavior
const c = a / b;
^
const c = a / b; 줄(4번째 줄)에서 **"division by zero here causes illegal behavior"**라는 오류가 표시돼요. 컴파일 타임 연산은 실행하기 전에 값이 다 정해져 있으니까, 컴파일러가 미리 위험을 감지해서 빌드를 막아버리는 거예요.
런타임에는 값이 실행 중에 정해지기 때문에 컴파일러가 미리 알 수 없어요. 대신 프로그램이 실제로 0으로 나누는 순간 다시 안전 검사를 통해 panic이 발생합니다.
const std = @import("std");
pub fn main() void {
var a: u32 = 1;
var b: u32 = 0;
_ = .{ &a, &b };
const c = a / b;
std.debug.print("value: {}\n", .{c});
}
Shell:
$ zig build-exe runtime_division_by_zero.zig
$ ./runtime_division_by_zero
thread 973591 panic: division by zero
/home/ci/work/zig-bootstrap/zig/doc/langref/runtime_division_by_zero.zig:7:17: 0x11e82b0 in main (runtime_division_by_zero.zig)
const c = a / b;
^
/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)
thread 973591 panic: division by zero 메시지와 함께 스택 트레이스가 출력되고, 프로세스가 신호에 의해 종료돼요. 잘못된 값을 조용히 넘기고 프로그램을 계속 돌리는 대신, 에러가 난 위치를 남겨서 문제를 바로 찾을 수 있게 하는 거죠.
정리하면, 0으로 나누기는 Zig에서 항상 잡히는 에러입니다. 컴파일 타임 상수 연산이라면 빌드가 실패하고, 런타임 연산이라면 panic으로 프로그램이 멈춰요. 어느 쪽이든 조용히 무시되고 지나가는 경우는 없어요.