크기와 정렬 보장

크기와 정렬 보장 (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) 속성이 보장돼요.

  1. 임의의 타입의 변수 x에 대해, unsafe.Alignof(x)는 최소 1이에요.
  2. 구조체 타입의 변수 x에 대해, unsafe.Alignof(x)x의 각 필드 f에 대한 unsafe.Alignof(x.f) 값들 중 가장 큰 값이에요. 다만 최소 1이에요.
  3. 배열 타입의 변수 x에 대해, unsafe.Alignof(x)는 배열의 요소 타입 변수의 정렬과 같아요.

구조체나 배열 타입은 크기가 0보다 큰 필드(또는 요소)를 하나도 담지 않으면 크기가 0이 돼요. 그리고 서로 다른 두 개의 크기 0인 변수는 메모리에서 같은 주소를 가질 수 있어요 — 실제로 컴파일러가 그렇게 배치할 수도 있다는 뜻이죠.

더 알아보기

  • 조금 더 엄밀하게, 이 보장은 어디까지나 '최소' 크기와 '최소' 정렬이에요. 그래서 실제로는 플랫폼에 따라 더 큰 값이 쓰일 수 있어요. 구체적인 배치를 확인하고 싶다면 unsafe.Sizeof, unsafe.Alignof, unsafe.Offsetof를 직접 찍어 보면 돼요.
  • 정렬과 패딩이 실제 코드에 어떤 영향을 주는지 볼 때는 구조체 레이아웃을 다루는 자료를 함께 보면 이해가 빨라져요.