C에서 타입 세이프(Generic)한 자료구조 작성법
카테고리
프로그래밍/소프트웨어 개발
서브카테고리
데이터 분석
대상자
- *C 언어 개발자 (중급~고급), 타입 안정성과 성능 최적화가 필요한 자료구조 구현 필요자**
핵심 요약
- union을 활용한 컴파일 타임 타입 체크 기법으로,
typeof(foo_list.payload)
와__typeof__
를 사용해 타입 정보를 자료구조에 연관 - 기존 방식(매크로, void 포인터)의 단점(가독성 저하, 메모리 낭비, 런타임 타입 오류)을 극복
- List(type) 매크로로
typedef List(Foo) ListFoo;
와 같은 방식으로 타입 안전한 인터페이스 생성 가능
섹션별 세부 요약
1. 기존 C 제네릭 패턴의 한계
- 매크로 기반 구조체/함수명 생성으로, 함수 중복 및 코드 추적 어려움
- void 포인터 사용 시 타입 체크 불가능, 런타임 오류 발생 가능
- Flexible Array Member는 메모리 효율성 향상 가능하지만,
memcpy
크기 정보 전달 필요
2. union 기반의 새로운 타입 세이프 기법
- union의 payload 멤버에 파라미터화된 타입 포인터 선언 예:
#define List(type) union { ListNode head; type payload; }
- 매크로(list_prepend)에서의 타입 캐스팅을 통해 컴파일 타임에 타입 검증 가능
- 예:
foo_list
에int
추가 시 'incompatible integer to pointer conversion' 컴파일 에러 발생
3. 실무 적용 및 장점
- typedef 활용으로
typedef List(Foo) ListFoo;
처럼 타입별 구조체/함수 인터페이스 관리 가능 - 해시맵, 배열, 트리 등 다양한 자료구조에 적용 가능
- 메모리 낭비 감소 및 캐시 효율성 향상 (노드와 데이터 한 번 할당)
결론
- union + typeof 기반의 타입 체크 기법을 사용해 C에서 타입 안전한 제네릭 자료구조를 구현할 수 있으며, 매크로 기반 방식의 단점(코드 중복, 유지보수성 저하)을 극복
- C23 이전 컴파일러에서는
__typeof__
대신struct
내 payload 멤버 활용 등 대체 방식 필요 - 타입 파라미터가 필요한 자료구조(예: 해시맵)에 효과적, 실습 예시는 관련 Gist 링크 참조