Hungarian 표기법 접두어 해독표 — 변수 이름만 보고 타입·스코프 짐작하기

NOTE

여러 팀이 오래 유지보수하는 통신/임베디드 C 코드베이스에서 여전히 흔히 쓰이는 Hungarian 표기법(변수·타입 접두어로 정보를 이름에 새기는 관례)을 해독하는 방법을 정리한다. 문법이 아니라 네이밍 관례지만, 이걸 모르면 선언부를 안 보고는 변수 이름만으로 아무것도 짐작할 수 없다.

0. 왜 필요한가

Hungarian 표기법을 쓰는 코드는 변수 이름 자체에 타입·스코프 정보를 압축해 넣도록 설계돼 있다. 표기법을 아는 사람에게는 이름만 보고도 선언부를 열어보지 않고 짐작이 가능하다는 게 장점이지만, 표기법 자체를 모르면 정반대로 모든 이름이 암호처럼 보인다. (실무 C 코드 관례와 UB 함정 정리의 A15에서 “팀 컨벤션”으로 짧게 언급한 내용을 여기서 접두어 단위로 풀어서 정리한다.)

1. 자료형 접두어

접두어의미예
n, iintn_count, i_idx
cchar (문자 하나)c_flag
sz널 종단 문자열(char 배열)sz_name
bbool/on-off 플래그(보통 0 또는 1인 int)b_enabled
ffloat/doublef_ratio
uunsigned (다른 접두어와 조합)un_count(unsigned int), uc_val(unsigned char), us_port(unsigned short)
st구조체(struct) 인스턴스st_msg
en열거형(enum) 값en_state

2. 스코프·형태 접두어

접두어의미예
g전역(global) 변수g_svcflag
s파일 스코프(static) 변수s_cache
p포인터 한 단계p_data (= int *p_data처럼 뒤 타입과 조합)
pp포인터의 포인터(두 단계)pp_list (= char **pp_list)
(대문자 시작)매크로 상수 / 컴파일 타임 상수MAX_RETRY

3. 접두어는 왼쪽에서 오른쪽으로, “스코프 → 포인터 단계 → 기본 타입” 순으로 조합된다

여러 접두어가 겹친 이름은 한 번에 읽으려 하지 말고, 앞에서부터 한 조각씩 떼어내며 해석한다.

gpst_conn_table
│││└─ conn_table : 의미상 이름 (연결 테이블)
││└── st         : 기본 타입 = 구조체(struct) 인스턴스를 가리킴
│└─── p          : 포인터 한 단계
└──── g          : 스코프 = 전역(global)

→ “전역(g) 포인터(p)가 가리키는 구조체(st) 타입의, 이름이 conn_table인 대상” = st_conn_table_t *gpst_conn_table;에 해당하는 변수라고 짐작할 수 있다. 실제 선언을 찾아 대조해보면 대부분 이 조합 순서(스코프 → 자료형/포인터 단계 → 의미상 이름)를 따른다.

4. 구조체 선언과 타입 정의에서의 관례 (_st_..._t)

변수뿐 아니라 typedef struct를 정의할 때도 일관된 관례가 적용된다:

typedef struct _st_nrf_udr_info_t {
    ...
} st_nrf_udr_info_t;
구성 요소의미설명
st_ / _st_Structure이 심볼이 구조체임을 나타냄
맨 앞 밑줄 _태그명 충돌 방지C 문법상 struct 태그명과 typedef 타입명이 네임스페이스를 공유할 때의 이름 충돌을 피하기 위해 태그명 앞에 관례적으로 언더스코어를 붙임
nrf_ / sbi_모듈 식별자네임스페이스가 없는 C 언어에서 다른 모듈과의 전역 심볼 충돌을 방지하기 위한 프리픽스
_tType (자료형)POSIX 표준(size_t, time_t) 및 C 관례로, typedef로 정의된 사용자 정의 자료형임을 명시

5. 함수 이름에서의 관례

  • 모듈 접두어: 같은 모듈에 속한 함수는 전부 같은 접두어로 시작해 이름 충돌을 피한다(자세한 내용: A13, 실무 C 코드 관례와 UB 함정 정리). 예: conn_create, conn_destroy, conn_send처럼 conn_이 모듈 경계를 나타낸다.
  • 동사_명사 순서: get_config, set_timeout처럼 “무엇을 하는지(동사)“가 앞, “무엇에 대해(명사)“가 뒤에 오는 순서가 흔하다.
  • 생성/소멸 접미어 쌍: _init/_destroy, _create/_free 같은 이름 쌍이 항상 함께 다닌다는 것 자체가 관례다(실무 C 코드 관례와 UB 함정 정리의 A1).

5. 주의점 — Hungarian 표기법의 한계

  • 이름과 실제 타입이 리팩터링 후 어긋날 수 있다 — n_count로 선언했던 변수를 나중에 unsigned int로 바꿔도, 이름의 n_ 접두어까지 자동으로 un_으로 바뀌진 않는다. 컴파일러는 이름과 실제 타입의 불일치를 잡아주지 않으므로, 이름은 참고일 뿐 실제 선언부의 타입이 항상 최종 진실이라는 걸 잊으면 안 된다.
  • 팀마다 접두어의 의미가 다를 수 있다 — 이 표는 통신/임베디드 C 코드베이스에서 흔히 보이는 조합을 정리한 것이지, 모든 프로젝트에 그대로 적용되는 표준은 아니다. 새 코드베이스에 들어가면 기존 코드에서 같은 접두어가 실제로 어떻게 쓰이고 있는지부터 확인하는 게 우선이다.
  • 표기법 자체가 3급(팀 컨벤션)이라는 점 — 옳고 그름의 문제가 아니라 “이 팀은 이렇게 쓴다”의 문제다. 최신 오픈소스 트렌드는 IDE의 타입 추론이 좋아지면서 Hungarian 표기법을 지양하는 쪽으로 가고 있지만, 오래 유지보수되는 코드베이스에 새 코드를 추가할 때는 주변 코드의 관례를 따르는 게 일관성 측면에서 낫다.

관련 문서