이식성 가이드
이식성 가이드 (Portability Guide)
D 언어를 여러 플랫폼에 걸쳐 쓸 때 생기는 이식성(portability) 문제를 최소화하는 방법을 다루는 챕터예요. 코드가 32비트와 64비트, 그리고 서로 다른 CPU 아키텍처에서도 올바르게 동작하도록 설계하는 데 꼭 필요한 내용을 정리해 봤어요.
본문
코드에 불필요한(gratuitous) 이식성 문제가 생기는 것을 최소화하는 것은 좋은 소프트웨어 공학 관행이에요. 잠재적인 이식성 문제를 최소화하기 위한 기법들은 이러해요:
-
정수형과 부동소수점형의 크기는 최솟값으로 간주하세요. 알고리즘은 타입의 크기가 커져도 계속 올바르게 동작하도록 설계해야 해요.
-
부동소수점 계산은 실제 변수 크기가 담을 수 있는 것보다 더 높은 정밀도로 수행될 수 있어요. 부동소수점 알고리즘은 정밀도가 임의로 높아져도 계속 올바르게 동작해야 해요.
-
컴파일러가 재배열(reorder)할 수 있는 계산에서 부작용(side effect)의 순서에 의존하지 마세요. 예를 들어:
a + b + c
이건 (a + b) + c, a + (b + c), (a + c) + b, (c + b) + a 등으로 평가될 수 있어요. 괄호는 연산자 우선순위(operator precedence)를 제어할 뿐, 평가 순서(order of evaluation)를 제어하지는 않아요.
결합(associative) 연산자 +나 *의 피연산자가 부동소수점 값이라면, 그 표현식은 재배열되지 않아요.
-
바이트 순서(byte order)에 의존하지 마세요. 즉 CPU가 빅 엔디언(big-endian)인지 리틀 엔디언(little-endian)인지에 의존하지 말라는 뜻이에요.
-
포인터나 참조(reference)의 크기가 특정 정수형과 같은 크기라는 점에 의존하지 마세요.
-
크기 의존성이 어쩔 수 없이 생긴다면, 코드에
static assert를 넣어 검증하세요:
static assert(int.sizeof == (int*).sizeof);
32비트에서 64비트로의 이식성 (32 to 64 Bit Portability)
32비트 프로세서와 운영체제는 아직도 현장에 존재해요. 이를 염두에 두신다면:
-
정수형의 크기는 32비트 코드와 64비트 코드 사이에서 동일하게 유지돼요.
-
포인터와 객체 참조는 32비트 코드에서 64비트 코드로 넘어가면서 4바이트에서 8바이트로 커져요.
-
size_t를 주소 공간(address space)을 아우를 수 있는 부호 없는 정수형의 별칭(alias)으로 사용하세요. 배열 인덱스는size_t타입이어야 해요. -
ptrdiff_t를 주소 공간을 아우를 수 있는 부호 있는 정수형의 별칭으로 사용하세요. 두 포인터 사이의 차이를 나타내는 타입은ptrdiff_t타입이어야 해요. -
.length,.size,.sizeof,.offsetof,.alignof프로퍼티는size_t타입이 돼요.
엔디언 (Endianness)
엔디언(endianness)은 다중 바이트(multibyte) 타입이 저장되는 순서를 말해요. 두 가지 주요 순서는 빅 엔디언(big endian) 과 리틀 엔디언(little endian) 이에요. 컴파일러는 대상 시스템의 순서에 따라 버전 식별자 BigEndian 또는 LittleEndian을 미리 정의해요. x86 시스템은 전부 리틀 엔디언이에요.
엔디언이 중요해지는 경우는 이러해요:
- 외부 소스(예: 파일)에서 다른 엔디언 형식으로 기록된 데이터를 읽을 때.
long이나double같은 다중 바이트 타입의 개별 바이트를 읽거나 쓸 때.
OS 관련 코드 (OS Specific Code)
시스템 특화 코드는 차이점을 별도의 모듈로 격리해서 처리해요. 컴파일 시점에 올바른 시스템 특화 모듈이 임포트되죠.
사소한 차이는 시스템 특화 임포트에 정의된 상수를 사용하고, 그 상수를 IfStatement나 StaticIfStatement에서 사용하는 방식으로 처리할 수 있어요.
더 알아보기 (Learn more)
- D 언어 사양(Language Reference) 전체 목차: https://dlang.org/spec/spec.html
- 32비트와 64비트 C 타입 크기 및
size_t,ptrdiff_t에 대한 더 자세한 내용: https://dlang.org/spec/type.html