유닛

유닛

유닛(unit)은 프로그램이나 다른 유닛이 사용할 수 있는 선언·프로시저·함수들을 묶어 놓은 단위예요. 코드를 모듈로 나누어 재사용하는 가장 기본적인 수단입니다.

출처: 문서

본문

유닛은 프로그램이나 다른 유닛이 사용할 수 있는 일련의 선언·프로시저·함수를 담고 있어요. 유닛의 문법은 다음과 같습니다.

문법 도식에서 볼 수 있듯이, 유닛은 항상 interface 부분과 implementation 부분으로 구성됩니다. 선택적으로 초기화 블록(initialization block)과 종료 블록(finalization block)이 있어서, 각각 프로그램이 시작될 때와 프로그램이 멈출 때 실행되는 코드를 담을 수 있어요.

interface 부분이나 implementation 부분은 둘 다 비어 있을 수 있지만, interfaceimplementation 키워드는 반드시 지정해야 합니다. 다음은 완전히 유효한 유닛이에요.

unit a;
interface
implementation
end.

interface 부분

interface 부분은 유닛에서 내보내야 하는 모든 식별자를 선언해요. 상수·타입·변수 식별자일 수도 있고, 프로시저·함수 식별자 선언일 수도 있습니다. interface 부분은 실행되는 코드를 포함할 수 없어요. 오직 선언만 허용됩니다. 다음은 유효한 interface 부분이에요.

unit a;
interface
uses b;
Function MyFunction : SomeBType;
Implementation

SomeBType 타입은 유닛 b에 정의되어 있어요. interface 부분에 선언된 모든 함수·메서드는 external 함수나 프로시저 선언을 제외하고는 반드시 유닛의 implementation 부분에서 구현되어야 합니다. 선언된 메서드나 함수가 implementation 부분에서 구현되지 않으면 컴파일러가 오류를 냅니다. 예를 들어 다음은

unit unita;
interface
Function MyFunction : Integer;
implementation
end.

이런 오류를 발생시킵니다.

unita.pp(5,10) Error: Forward declaration not solved "MyFunction:SmallInt;"

implementation 부분

implementation 부분은 주로 interface 부분에서 선언된 함수·프로시저를 구현하는 용도로 쓰여요. 하지만 자체 선언도 포함할 수 있는데, implementation 부분 안의 선언은 유닛 밖에서는 접근할 수 없어요.

초기화·종료 부분

유닛의 초기화(initialization)와 종료(finalization) 부분은 선택적이에요. 초기화 블록은 특정 변수를 초기화하거나 유닛이 올바르게 동작하는 데 필요한 코드를 실행할 때 사용합니다.

  • 유닛들의 초기화 부분은 컴파일러가 프로그램을 컴파일할 때 유닛을 로드한 순서대로 실행되어요. 프로그램의 첫 문장이 실행되기 전에 실행됩니다.
  • 종료 부분은 초기화 실행 순서의 역순으로 실행돼요. 예를 들어 초기화 부분이나 프로그램 수명 동안 할당한 리소스를 정리하는 데 사용합니다.

종료 부분은 프로그램이 정상 종료되는 경우 항상 실행돼요. 프로그램 코드에서 마지막 end에 도달했든, 어딘가에서 Halt 명령이 실행됐든 상관없이요. 프로그램이 어떤 유닛의 초기화 블록을 실행하는 도중에 멈춘다면, 이미 초기화된 유닛들만 종료됩니다.

Delphi와 달리 Free Pascal에서는 finalization 블록이 Initialization 블록 없이 존재할 수 있다는 점이 흥미로워요. 즉 다음은 Free Pascal에서는 컴파일되지만 Delphi에서는 컴파일되지 않습니다.

Finalization
  CleanupUnit;
end.

초기화 섹션만 있고 종료가 없는 경우는 단순히 문장 블록으로 대체할 수 있어요. 즉 다음은

Initialization
  InitializeUnit;
end.

다음과 완전히 동등합니다.

Begin
  InitializeUnit;
end.

더 알아보기