타입 별칭

타입 별칭 (Type aliases)

이미 있는 타입에 이름을 하나 더 붙이고 싶을 때가 있어요. 그런데 Free Pascal에서는 별칭을 만드는 방식에 따라 이름만 추가되는지, 완전히 새로운 타입이 생기는지가 갈려요. 이 둘의 차이를 이번 절에서 확실히 짚어 볼게요.

출처: 문서

본문

타입 별칭(type alias) 은 타입에 다른 이름을 붙이는 방법이에요. 그런데 실제로는 완전히 새로운 타입을 만드는 데도 쓰일 수 있어요. 둘 중 어느 쪽인지는 타입 별칭을 어떻게 정의하느냐에 달려 있어요.

첫 번째 경우는 단순히 타입에 다른 이름을 붙이는 거예요:

Type

MyInteger = Integer;

이건 Integer 타입을 가리킬 새 이름을 만들지만, 실제 새 타입을 만들지는 않아요. 즉 다음 두 변수는

Var

A : MyInteger;

B : Integer;

컴파일러 관점에서 실제로 같은 타입(즉 Integer)을 가져요.

이 방식으로 플랫폼 독립적인 타입을 만들 수 있어요. 별칭 타입만 쓰고, 각 플랫폼마다 이 타입들을 개별적으로 정의해 두는 거예요. 그러면 커스텀 타입을 쓰는 프로그래머는 밑바탕이 되는 타입의 크기를 신경 쓸 필요가 없어요. 그건 그에게 불투명하니까요. 또 정규화된 타입 이름의 단축 이름으로도 쓸 수 있어요. 예를 들어 system.longintOlongint로 정의한 뒤 longint를 다시 정의하는 식이에요.

별칭은 타입을 다시 드러내는 데(re-expose) 자주 쓰여요:

Unit A;

Interface

Uses B;

Type

MyType = B.MyType;

이런 구조는 리팩토링 후에 자주 보여요. unit A에서 unit B로 일부 선언을 옮기면서 unit A의 인터페이스의 하위 호환성을 유지하려고 할 때죠.

두 번째 경우는 조금 더 미묘해요:

Type

MyInteger = Type Integer;

이건 Integer 타입을 가리킬 새 이름을 만들 뿐 아니라 실제로 새 타입을 만들어요. 즉 다음 두 변수는

Var

A : MyInteger;

B :  Integer;

컴파일러 관점에서 같은 타입이 아니에요. 다만 이 두 타입은 대입 호환이 가능해요. 즉 대입

A:=B;

은 동작해요.

이 차이는 타입 정보를 살펴보면 확인할 수 있어요:

If TypeInfo(MyInteger)<>TypeInfo(Integer) then

Writeln('MyInteger and Integer are different types');

컴파일러 함수 TypeInfo는 바이너리 안의 타입 정보에 대한 포인터를 반환해요. MyIntegerInteger가 서로 다른 타입이므로 서로 다른 타입 정보 블록이 생성되고, 포인터도 달라져요.

타입이 다르다는 데서 세 가지 결과가 따라와요:

  • 다른 typeinfo를 갖고, 따라서 다른 RTTI(Run-Time Type Information) 를 가져요.

  • 함수 오버로드에 쓸 수 있어요.

    Procedure MyProc(A : MyInteger); overload;
    
    Procedure MyProc(A : Integer); overload;
    

    이건 동작해요. 하지만 단순 타입 별칭으로는 동작하지 않아요.

  • 연산자 오버로드에 쓸 수 있어요.

    Operator +(A,B : MyInteger) : MyInteger;
    

    이것도 동작해요.

더 알아보기

  • 타입별 RTTI와 typeinfo에 대해서는 런타임 타입 정보 관련 절에서 다뤄요.
  • 함수·연산자 오버로드에 대해서는 각각의 절에서 더 자세히 살펴볼 수 있어요.