Cast Truncates Data

Cast Truncates Data

좁은 타입으로 캐스팅할 때 값이 그 타입에 담기지 못할 만큼 크면 어떻게 될까요? Zig는 이런 상황을 조용히 넘어가지 않고 컴파일 타임이든 런타임이든 분명하게 실패시켜요. 값이 타입에 맞지 않으면 자동으로 잘리지(truncate) 않는다는 뜻이에요.

출처: Zig Documentation

본문

컴파일 타임에는

컴파일 타임에 u16 값을 u8로 캐스팅하면, 값이 u8이 표현할 수 있는 범위를 벗어나므로 즉시 컴파일 오류가 나요.

comptime {
    const spartan_count: u16 = 300;
    const byte: u8 = @intCast(spartan_count);
    _ = byte;
}

이 코드를 실행하면 다음과 같은 오류가 발생해요.

$ zig test test_comptime_invalid_cast_truncate.zig
/home/ci/work/zig-bootstrap/zig/doc/langref/test_comptime_invalid_cast_truncate.zig:3:31: error: type 'u8' cannot represent integer value '300'
    const byte: u8 = @intCast(spartan_count);
                              ^~~~~~~~~~~~~

런타임에는

마찬가지로 런타임에 확인된 값이 타입에 안 들어가면 캐스팅이 아니라 **패닉(panic)**이 일어나요. 프로그램이 그 자리에서 멈추는 거죠.

const std = @import("std");

pub fn main() void {
    var spartan_count: u16 = 300; // runtime-known
    _ = &spartan_count;
    const byte: u8 = @intCast(spartan_count);
    std.debug.print("value: {}\n", .{byte});
}
$ zig build-exe runtime_invalid_cast_truncate.zig
$ ./runtime_invalid_cast_truncate
thread 972446 panic: integer does not fit in destination type
/home/ci/work/zig-bootstrap/zig/doc/langref/runtime_invalid_cast_truncate.zig:6:22: 0x11e82a0 in main (runtime_invalid_cast_truncate.zig)
    const byte: u8 = @intCast(spartan_count);
                     ^
/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)

그렇다면 정말로 비트를 잘라서 캐스팅하고 싶을 때는 어떻게 할까요? 그럴 땐 캐스팅이 아니라 @truncate를 사용해요.

더 알아보기