@bitCast — 타입은 바꾸되 비트 표현은 그대로
@bitCast — 타입은 바꾸되 비트 표현은 그대로
한 값의 타입만 다른 타입으로 바꾸고 싶다면? 포인터가 아니라 메모리 상의 비트 배열 그 자체를 다른 타입으로 해석하고 싶을 때 @bitCast를 써요. 값의 비트 표현(bit representation)은 그대로 두고, 그 비트를 읽는 "안경"만 다른 타입으로 바꾸는 셈이에요.
본문
@bitCast는 어떤 타입의 값을 다른 타입으로 변환해요. 반환 타입은 추론된 결과 타입(inferred result type)이에요. 즉 "어디로 바꿀지"는 호출 문맥에서 결정된다는 뜻이에요.
@bitCast(value: anytype) anytype
이 변환은 두 가지를 컴파일 타임에 단언(assert) 해요.
@sizeOf(@TypeOf(value)) == @sizeOf(DestType)— 원본 값의 크기와 목적 타입의 크기가 같아야 해요. 비트 수가 같아야 비트를 그대로 재해석할 수 있으니까요.@typeInfo(DestType) != .pointer— 목적 타입이 포인터면 안 돼요. 포인터로 메모리를 재해석해야 한다면@ptrCast나@ptrFromInt를 써야 해요.
예를 들어 이런 작업에 쓸 수 있어요.
f32를u32의 비트로 변환하기i32를u32로 변환하되 2의 보수(twos complement) 비트를 그대로 보존하기
value가 컴파일 시점에 알려져 있으면 @bitCast는 컴파일 타임에도 동작해요.
한 가지 꼭 짚어둘 게 있어요. 메모리 레이아웃이 정의되지 않은(undefined layout) 값을 bitcast 하는 건 컴파일 오류예요. 어떤 타입들이 안 되느냐 하면요.
- 전용 캐스팅 빌트인이 따로 있는 타입 (포인터, 에러 셋)
- 빈 구조체(bare struct), 에러 유니온(error union), 슬라이스, 옵셔널(optional)
- 그 외에도 메모리 레이아웃이 명확히 정의되지 않은 모든 타입
이런 타입들은 "비트가 어떤 식으로 배치돼 있는지"가 보장되지 않으니, 비트를 그대로 들고 가는 @bitCast에 쓰이는 게 처음부터 차단돼 있어요.
또 하나, 대응하는 태그 값(tag value)이 없는 정수를 enum으로 바꾸려는 시도는 안전 검사가 걸린 Illegal Behavior(safety-checked Illegal Behavior)를 불러일으켜요.
더 알아보기 (Learn more)
연관된 캐스팅 빌트인들을 함께 봐두면 상황별로 뭘 써야 할지 분명해져요.
- @ptrCast — 포인터 타입 간 재해석
- @intFromPtr — 포인터를 정수로
- @ptrFromInt — 정수를 포인터로
- @errorCast — 에러 셋 캐스팅
- @intFromError — 에러 값을 정수로
- @errorFromInt — 정수를 에러 값으로
- @backingInt — enum의 backing 정수 추출
- @fromBackingInt — 정수에서 enum 생성