크기와 정렬 보장
크기와 정렬 보장 (Size and alignment guarantees)
Go 프로그램을 짜다 보면 "이 타입이 메모리에서 몇 바이트를 차지하지?" 같은 질문이 생길 때가 있어요. 이 값이 전부 플랫폼에 따라 마음대로 바뀐다면 코드를 이식하기가 무척 어렵겠죠. 그래서 Go 명세는 숫자 타입(numeric types)의 크기와 정렬에 대한 최소한의 보장을 명확히 박아 두고 있어요. 이걸 알면 unsafe 패키지를 쓸 때든, 구조체 메모리 배치를 생각할 때든 헷갈리지 않아요.
출처: Go Specification
본문
숫자 타입에 대해서는 다음 크기가 보장돼요.
type size in bytes
byte, uint8, int8 1
uint16, int16 2
uint32, int32, float32 4
uint64, int64, float64, complex64 8
complex128 16
그리고 다음의 최소 정렬(minimal alignment) 속성이 보장돼요.
- 임의의 타입의 변수
x에 대해,unsafe.Alignof(x)는 최소 1이에요. - 구조체 타입의 변수
x에 대해,unsafe.Alignof(x)는x의 각 필드f에 대한unsafe.Alignof(x.f)값들 중 가장 큰 값이에요. 다만 최소 1이에요. - 배열 타입의 변수
x에 대해,unsafe.Alignof(x)는 배열의 요소 타입 변수의 정렬과 같아요.
구조체나 배열 타입은 크기가 0보다 큰 필드(또는 요소)를 하나도 담지 않으면 크기가 0이 돼요. 그리고 서로 다른 두 개의 크기 0인 변수는 메모리에서 같은 주소를 가질 수 있어요 — 실제로 컴파일러가 그렇게 배치할 수도 있다는 뜻이죠.
더 알아보기
- 조금 더 엄밀하게, 이 보장은 어디까지나 '최소' 크기와 '최소' 정렬이에요. 그래서 실제로는 플랫폼에 따라 더 큰 값이 쓰일 수 있어요. 구체적인 배치를 확인하고 싶다면
unsafe.Sizeof,unsafe.Alignof,unsafe.Offsetof를 직접 찍어 보면 돼요. - 정렬과 패딩이 실제 코드에 어떤 영향을 주는지 볼 때는 구조체 레이아웃을 다루는 자료를 함께 보면 이해가 빨라져요.