인덱스 범위를 벗어난 접근

인덱스 범위를 벗어난 접근 (Index out of Bounds)

배열이나 슬라이스에 array[5]처럼 인덱스를 벗어나게 접근하면 컴파일러가 가만히 두지 않아요. 그 접근이 컴파일 타임에도 일어나는지, 아니면 실행 중에 일어나는지에 따라 처리 방식이 조금 달라지는데, 두 경우를 나란히 확인해 볼게요.

출처: Zig Documentation

본문

컴파일 타임

컴파일러가 값의 길이를 알 수 있는 상황(컴파일 타임)에서는, 범위를 벗어난 인덱스를 컴파일 에러로 잡아 줍니다.

comptime {
    const array: [5]u8 = "hello".*;
    const garbage = array[5];
    _ = garbage;
}
$ zig test test_comptime_index_out_of_bounds.zig
/home/ci/work/zig-bootstrap/zig/doc/langref/test_comptime_index_out_of_bounds.zig:3:27: error: index 5 outside array of length 5
    const garbage = array[5];
                          ^

길이 5짜리 배열에 인덱스 5로 접근하려다 index 5 outside array of length 5라는 컴파일 에러를 받았어요. 컴파일러가 array[5]가 배열 밖을 가리킨다는 걸 미리 알아챈 거죠.

런타임

길이가 실행 중에만 알려지는 상황(예: 함수로 슬라이스를 받았을 때)에서는 컴파일 타임에 잡을 수 없어요. 이 경우에는 **실행 도중 안전성 검사(runtime safety check)**가 발동해서, 범위를 벗어나면 패닉(panic)을 일으킵니다.

pub fn main() void {
    const x = foo("hello");
    _ = x;
}

fn foo(x: []const u8) u8 {
    return x[5];
}
$ zig build-exe runtime_index_out_of_bounds.zig
$ ./runtime_index_out_of_bounds
thread 972133 panic: index out of bounds: index 5, len 5
/home/ci/work/zig-bootstrap/zig/doc/langref/runtime_index_out_of_bounds.zig:7:13: 0x11e836e in foo (runtime_index_out_of_bounds.zig)
    return x[5];
            ^
/home/ci/work/zig-bootstrap/zig/doc/langref/runtime_index_out_of_bounds.zig:2:18: 0x11e829a in main (runtime_index_out_of_bounds.zig)
    const x = foo("hello");
                 ^
/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)

여기서 foo가 받은 x는 슬라이스라 길이가 컴파일 타임에 확정되지 않았어요. 그래서 x[5]에 도달하는 순간 panic: index out of bounds: index 5, len 5라는 메시지와 함께 프로세스가 종료됐죠. index 5가 접근하려던 인덱스, len 5가 실제 길이예요.

더 알아보기 (Learn more)

인덱스로 접근하는 대상의 기본 개념을 복습하고 싶다면 여기를 살펴보세요.