D 언어 사양 — Introduction
D 언어 사양 — Introduction (소개)
D는 C와 비슷한 문법을 가진 범용 시스템 프로그래밍 언어예요. 소스 코드가 네이티브(native) 코드로 컴파일된다는 점이 큰 특징인데요. 정적으로 타입이 지정되고, 자동(가비지 컬렉션) 메모리 관리와 수동 메모리 관리를 모두 지원합니다.
D 프로그램은 모듈(module) 단위로 구조화됩니다. 각각의 모듈은 따로 컴파일할 수 있고, 외부 라이브러리와 링크해서 네이티브 라이브러리나 실행 파일을 만들 수 있어요.
이 문서는 D 프로그래밍 언어의 레퍼런스 매뉴얼(reference manual) 입니다. 더 많은 정보와 다른 문서들은 The D Language Website에서 확인할 수 있어요.
본문
Phases of Compilation (컴파일 단계)
컴파일 과정은 여러 단계로 나뉩니다. 각 단계는 뒤따르는 단계와 독립적이에요. 예를 들어 스캐너(scanner)는 시맨틱 분석기(semantic analyzer)의 영향을 받지 않죠. 이렇게 패스(pass)를 분리해 두면 문법 지향 편집기(syntax-directed editor) 같은 언어 도구를 비교적 쉽게 만들 수 있습니다.
컴파일은 다음과 같은 순서로 진행됩니다.
- source character set (소스 문자 집합) — 소스 파일의 인코딩을 확인하고, 그에 맞는 스캐너를 불러옵니다. 7-bit ASCII와 UTF 인코딩을 지원해요.
- script line (스크립트 줄) — 첫 줄이
#!로 시작하면 그 줄은 무시됩니다. - lexical analysis (어휘 분석) — 소스 파일을 토큰(token)의 연속으로 나눕니다. 특수 토큰(Special tokens)은 다른 토큰으로 치환되고, SpecialTokenSequence는 처리된 뒤 제거됩니다.
- syntax analysis (구문 분석) — 토큰의 연속을 파싱해서 구문 트리(syntax tree) 를 만듭니다.
- semantic analysis (시맨틱 분석) — 구문 트리를 탐색하면서 변수를 선언하고, 심볼 테이블(symbol table)을 채우고, 타입을 지정하고, 프로그램의 의미를 결정합니다.
- optimization (최적화) — 선택 사항인 패스로, 프로그램을 의미적으로 동등하면서 더 성능이 좋은 버전으로 다시 작성하려고 시도합니다.
- code generation (코드 생성) — 타깃 아키텍처에서 프로그램의 의미를 구현할 명령어(instruction)를 선택합니다. 일반적인 결과물은 링커(linker) 입력으로 적합한 오브젝트 파일(object file) 입니다.
Memory Model (메모리 모델)
byte(바이트) 는 저장소의 기본 단위예요. 각 바이트는 8비트이고, 고유한 주소에 저장됩니다. memory location(메모리 위치) 은 스칼라 타입 하나를 담는 데 필요한 정확한 크기의, 한 개 이상의 연속된 바이트입니다. 여러 스레드가 서로 다른 메모리 위치에는 간섭 없이 접근할 수 있어요.
메모리 위치는 세 가지 그룹으로 나뉩니다.
- Thread-local memory locations (스레드 지역 메모리 위치) — 한 번에 오직 하나의 스레드에서만 접근할 수 있어요.
- Immutable memory locations (불변 메모리 위치) — 수명 동안 쓰기할 수 없습니다. 여러 스레드가 동기화 없이 읽을 수는 있어요.
- Shared memory locations (공유 메모리 위치) — 여러 스레드에서 접근할 수 있어요.
Undefined Behavior (정의되지 않은 동작): 여러 스레드가 스레드 지역 메모리 위치에 접근하도록 허용하면 정의되지 않은 동작이 됩니다.
Undefined Behavior (정의되지 않은 동작): 불변 메모리 위치에 수명 동안 쓰기하는 것은 정의되지 않은 동작이에요.
Undefined Behavior (정의되지 않은 동작): 한 스레드가 공유 메모리 위치에 쓰는 동안, 하나 이상의 다른 스레드가 같은 위치를 읽거나 쓰는 것은 — 모든 읽기와 쓰기가 동기화되지 않는다면 — 정의되지 않은 동작입니다.
단일 스레드가 스레드 지역 메모리 위치와 불변 메모리 위치에서 실행하는 것은 sequentially consistent(순차적 일관성) 입니다. 즉 연산들의 전체 결과가, 프로그램에 나타난 순서 그대로 실행된 것과 동일하다는 뜻이에요.
메모리 위치가 그 위치에 대한 참조가 하나뿐이라면, 스레드 지역에서 불변 또는 공유로 옮길(transfer) 수 있습니다.
마찬가지로 참조가 하나뿐이라면 메모리 위치를 공유에서 불변 또는 스레드 지역으로 옮길 수 있어요.
그리고 메모리 위치는 동기화를 사용해 그 동안 다른 스레드가 접근하지 못하게 막는다면, 공유에서 임시로 지역(local) 으로 옮길 수도 있습니다.
Object Model (객체 모델)
object(객체) 는 다음 상황에서 생성됩니다.
- 정의(definition)
- NewExpression
- 임시 객체(temporary)가 생성될 때
- 유니온(union)의 활성 필드가 바뀔 때
객체는 일련의 메모리 위치에 걸쳐 있는데, 그 위치들이 연속적일 수도 있고 아닐 수도 있어요. 객체의 수명(lifetime)은 생성(construction), 소멸(destruction), 그리고 그 사이의 기간을 모두 포함합니다.
각 객체는 타입을 가지며, 그 타입은 정적으로 결정되거나 런타임 타입 정보(runtime type information) 로 결정됩니다. 객체의 메모리 위치는 스레드 지역, 불변, 공유 중 어떤 조합이든 포함할 수 있어요.
객체들은 composed object(합성 객체) 로 묶일 수 있습니다. 합성 객체를 이루는 객체들을 subobject(부분 객체) 라고 하고, 다른 객체의 부분 객체가 아닌 객체는 complete object(완전 객체) 라고 해요. 부분 객체의 수명은 항상 그것이 속한 완전 객체의 수명 안에 있습니다.
객체의 주소(address) 는 그 객체의 첫 번째 메모리 위치의 첫 번째 바이트 주소입니다. 객체 주소는 서로 구분되는데, 한 객체가 다른 객체 안에 중첩(nested) 돼 있는 경우는 예외예요.
Arithmetic (산술)
Integer Arithmetic (정수 산술)
정수 산술은 two's complement(2의 보수) 수학으로 수행됩니다. 정수 오버플로우(overflow)는 검사하지 않아요.
Floating Point Arithmetic (부동소수점 산술)
부동소수점 산술은 IEEE-754 부동소수점 수학으로 수행됩니다.
더 알아보기 (Learn more)
- 이 챕터에는 코드 블록이 없어요. 이어지는 챕터는 Lexical (어휘) 입니다.
- 전체 사양 목록: D Language Specification