Quick Syntax
enum은 상태·모드처럼 이름 있는 정수 값 집합을 만들고, typedef는 기존 타입 표기를 짧게 만듭니다. 값의 의미와 타입 표기는 별개의 역할입니다.
typedef enum {
STATUS_OK,
STATUS_WARN,
STATUS_ERROR
} Status;
typedef struct {
int x;
int y;
} Point;
enum { FLAG_READ = 1u << 0, FLAG_WRITE = 1u << 1 };
unsigned permissions = FLAG_READ | FLAG_WRITE;상태 하나를 고를 때는 enum을, 여러 옵션을 동시에 조합해야 하면 unsigned mask를 씁니다. typedef는 그 타입을 쓰는 표기만 바꿉니다.
문법
enum은 이름 있는 정수 상수 묶음이고, typedef는 기존 타입에 별칭을 붙이는 문법입니다.
enum Color {
COLOR_RED,
COLOR_GREEN,
COLOR_BLUE
};
typedef unsigned char byte;둘을 같이 쓰면 enum으로 값 집합을 만들고, typedef로 타입 이름을 짧게 만들 수 있습니다.
typedef enum {
MODE_READ,
MODE_WRITE
} Mode;enum Mode의 tag와 Mode라는 typedef 이름은 서로 다른 이름 공간에 있습니다. typedef를 쓰지 않으면 변수 선언에는 enum Mode mode;처럼 tag를 적어야 합니다.
역할 구분
enum이 유용한 순간은 매직 넘버를 상태 이름으로 치울 때입니다.
if (state == STATUS_ERROR) {
fprintf(stderr, "error\n");
}반면 typedef는 타입 문장을 짧게 만들어 읽기 비용을 줄일 때 유용합니다.
typedef struct {
int x;
int y;
} Point;enumerator는 기본적으로 앞 값보다 1 큰 정수 상수입니다. 프로토콜이나 파일 형식처럼 값이 계약이면 명시적으로 적고, 값이 중복될 수 있다는 점도 의식해야 합니다.
enum Result { RESULT_OK = 0, RESULT_RETRY = 10, RESULT_FAILED = 20 };연속된 상태 이름에는 enum이 잘 맞지만, 여러 비트를 조합하는 flags에는 enum 이름과 unsigned mask를 함께 쓰는 편이 낫습니다. 마지막 값인 COUNT sentinel은 배열 크기에는 유용하지만 외부 입력의 유효성 검사는 대신하지 않습니다.
즉 이 카드에서 같이 봐야 하는 것은:
- 값 자체에 이름을 붙일 것인가:
enum - 타입 표기를 줄일 것인가:
typedef
빠른 점검
switch (state) {
case STATUS_OK:
break;
case STATUS_WARN:
break;
case STATUS_ERROR:
break;
}enum은 이름 있는 정수 상수 집합입니다.typedef는 새 타입 체계를 만드는 것이 아니라 기존 타입의 별칭입니다.- 상태, 모드, 방향처럼 값 후보가 정해진 경우
enum이 잘 맞습니다. - 자주 읽는 구조체나 함수 포인터 이름을 줄일 때
typedef가 유용합니다. typedef enum은 값 집합과 짧은 타입 이름이 둘 다 필요할 때 자주 씁니다.
주의할 점
enum을 쓴다고 값 검증이 자동으로 생기지는 않습니다. 내부 표현은 결국 정수라서 외부 입력이나 파일 데이터에서 온 값은 여전히 범위 검사를 직접 해야 합니다.
참고 링크
2 sources