typedef 선언
typedef 선언
복잡한 타입 이름을 매번 다시 쓰는 건 번거롭죠. typedef 선언은 식별자를 타입 별칭으로 선언해서, 어쩌면 복잡할 수도 있는 타입 이름을 더 짧고 읽기 좋은 이름으로 바꿔 쓸 수 있게 해줘요.
출처: cppreference
본문
typedef 키워드는 선언 안에서 저장 기간 지정자(storage-class specifier)가 놓이는 문법 자리에 쓰여요. 다만 저장 기간이나 링키지에는 아무 영향도 주지 않는다는 점이 달라요.
typedef int int_t; // declares int_t to be an alias for the type int
typedef char char_t, *char_p, (*fp)(void); // declares char_t to be an alias for char
// char_p to be an alias for char*
// fp to be an alias for char(*)(void)
동작 방식
선언이 typedef를 저장 기간 지정자로 쓰면, 그 선언의 **모든 선언자(declarator)**가 지정한 타입에 대한 별칭을 정의해요. 한 선언에는 저장 기간 지정자가 하나만 허용되므로, typedef 선언은 static이나 extern이 될 수 없어요.
typedef 선언은 새로운 별개의 타입을 도입하지 않아요. 이미 있는 타입에 대한 동의어(synonym)를 만들 뿐이라, typedef 이름은 별칭으로 가리키는 타입과 **호환(compatible)**돼요. typedef 이름은 열거자, 변수, 함수 같은 일반 식별자들과 같은 이름 공간을 공유해요.
VLA(가변 길이 배열)에 대한 typedef는 블록 스코프에서만 나타날 수 있어요. 배열의 길이는 배열 선언 자체와 달리, 제어 흐름이 typedef 선언을 지날 때마다 평가돼요.
void copyt(int n)
{
typedef int B[n]; // B is a VLA, its size is n, evaluated now
n += 1;
B a; // size of a is n from before +=1
int b[n]; // a and b are different sizes
for (int i = 1; i < n; i++)
a[i-1] = b[i];
}
(C99부터)
참고
typedef 이름은 미완성 타입(불완전 타입, incomplete type)일 수도 있는데, 보통처럼 나중에 완성할 수 있어요.
typedef int A[]; // A is int[]
A a = {1, 2}, b = {3,4,5}; // type of a is int[2], type of b is int[3]
typedef 선언은 태그 이름 공간(tag name space)의 이름을 일반 이름 공간으로 끌어들일 때 자주 쓰여요.
typedef struct tnode tnode; // tnode in ordinary name space
// is an alias to tnode in tag name space
struct tnode {
int count;
tnode *left, *right; // same as struct tnode *left, *right;
}; // now tnode is also a complete type
tnode s, *sp; // same as struct tnode s, *sp;
태그 이름 공간을 아예 쓰지 않게 만들 수도 있어요.
typedef struct { double hi, lo; } range;
range z, *zp;
typedef 이름은 복잡한 선언의 문법을 단순화하는 데도 흔히 쓰여요.
// array of 5 pointers to functions returning pointers to arrays of 3 ints
int (*(*callbacks[5])(void))[3];
// same with typedefs
typedef int arr_t[3]; // arr_t is array of 3 int
typedef arr_t* (*fp)(void); // pointer to function returning arr_t*
fp callbacks[5];
라이브러리는 시스템 의존적이거나 설정 의존적인 타입을 typedef 이름으로 노출해, 사용자나 다른 라이브러리 구성 요소에게 일관된 인터페이스를 제공하곤 해요.
#if defined(_LP64)
typedef int wchar_t;
#else
typedef long wchar_t;
#endif
키워드
typedef
더 알아보기
- 타입 이름과 타입 분류의 전반은 타입(Type) 문서에서 이어서 볼 수 있어요.
typedef로 만든 별칭은 원래 타입과 항상 호환되므로, 호환 타입(compatible type)의 의미를 함께 이해하면 좋아요.- C++의
typedef선언도 같은 개념을 다루니 비교해 보세요.