식별자
식별자 (identifier)
변수 이름, 함수 이름, 구조체 태그처럼 코드 안에서 어떤 대상을 가리키는 이름을 식별자라고 해요. C에서는 식별자를 만들 때 지켜야 할 규칙이 있어서, 어떤 문자 조합이 이름으로 쓸 수 있는지 아는 게 먼저예요.
출처: cppreference
본문
식별자는 숫자, 밑줄, 소문자·대문자 라틴 문자, 그리고 \u와 \U 이스케이프 표기로 지정한 유니코드 문자(C99부터)로 이루어진 임의로 긴 문자 나열이에요. 이때 유니코드 문자는 XID_Continue 클래스에 속해야 해요(C23부터).
유효한 식별자는 숫자가 아닌 문자로 시작해야 해요(라틴 문자, 밑줄, 또는 C23 이전에는 유니코드의 숫자가 아닌 문자, C23부터는 XID_Start 클래스의 유니코드 문자). 식별자는 대소문자를 구분해요(소문자와 대문자는 서로 다른 이름이에요).
모든 식별자는 유니코드 정규화 형식 C(Normalization Form C)를 따라야 해요. (C23부터)
char * \U0001f431 = "cat" ; // supported
char * 🐱 = "cat" ; // implementation-defined
// (e.g. works with Clang, but not GCC prior to version 10)
// both are ill formed in C23. Emoji are not XID_Start characters
(C99부터, C23 이전)
식별자가 나타낼 수 있는 것
식별자는 다음 종류의 대상을 나타낼 수 있어요.
- 객체(object)
- 함수
- 태그(tag):
struct,union, 또는 열거형 - 구조체 또는 공용체의 멤버
- 열거형 상수
- typedef 이름
- 레이블 이름
- 매크로 이름
- 매크로 매개변수 이름
예약된 식별자
표준 라이브러리는 자기가 제공하는 모든 식별자를 예약해요. 외부 연결(external linkage)을 갖는 예약 식별자(모든 표준 함수의 이름 등)는 어떤 헤더를 포함하든 항상 예약돼요. 다른 예약 식별자는 연관된 헤더 중 하나를 포함할 때 예약돼요.
다음 식별자들은 구현을 위해, 또는 표준 라이브러리의 향후 사용을 위해 예약되거나 잠재적으로 예약돼 있어요(C23부터).
- 함수 이름 — 전부 잠재적으로 예약(C23부터)
<complex.h>에서cerf,cerfc,cexp2,cexpm1,clog10,clog1p,clog2,clgamma,ctgamma,csinpi,ccospi,ctanpi,casinpi,cacospi,catanpi,ccompoundn,cpown,cpowr,crootn,crsqrt,cexp10m1,cexp10,cexp2m1,clog10p1,clog2p1,clogp1(이상 C23)와 그-f,-l접미사 변형(C99부터).is또는to다음에 소문자가 오는,<ctype.h>와<wctype.h>의 이름(C95부터).str또는wcs(C23부터) 다음에 소문자가 오는,<stdlib.h>와<inttypes.h>의 이름(C23부터).<math.h>에서cr_로 시작하는 이름(C23부터).wcs다음에 소문자가 오는<wchar.h>의 이름(C95부터).atomic_다음에 소문자가 오는<stdatomic.h>의 이름(C11부터).cnd_,mtx_,thrd_,tss_다음에 소문자가 오는<threads.h>의 이름(C11부터).
- typedef 이름 — 전부 잠재적으로 예약(C23부터)
int나uint로 시작하고_t로 끝나는<stdint.h>의 이름(C99부터).atomic_이나memory_다음에 소문자가 오는<stdatomic.h>의 이름(C11부터).cnd_,mtx_,thrd_,tss_다음에 소문자가 오는<threads.h>의 이름(C11부터).
- 매크로 이름
E다음에 숫자 또는 대문자가 오는<errno.h>의 이름.FE_다음에 대문자가 오는<fenv.h>의 이름(C99부터).DBL_,DEC32_,DEC64_,DEC128_,DEC_,FLT_,LDBL_다음에 대문자가 오는<float.h>의 이름(C23부터 잠재적으로 예약).INT나UINT로 시작하고_MAX,_MIN,_WIDTH(C23부터), 또는_C로 끝나는<stdint.h>의 이름(C99부터; C23부터 잠재적으로 예약).PRI나SCN다음에 소문자 또는X가 오는<inttypes.h>의 이름(C99부터; C23부터 잠재적으로 예약).LC_다음에 대문자가 오는<locale.h>의 이름.FP_다음에 대문자가 오는<math.h>의 이름(C23부터).MATH_다음에 대문자가 오는<math.h>의 이름(C23부터 잠재적으로 예약).SIG나SIG_다음에 대문자가 오는<signal.h>의 이름.TIME_다음에 대문자가 오는<time.h>의 이름(C11부터).ATOMIC_다음에 대문자가 오는<stdatomic.h>의 이름(C11부터; C23부터 잠재적으로 예약).
- 열거형 상수 — 전부 잠재적으로 예약(C23부터)
memory_order_다음에 소문자가 오는<stdatomic.h>의 이름(C11부터).cnd_,mtx_,thrd_,tss_다음에 소문자가 오는<threads.h>의 이름(C11부터).
구현 제한
구현은 다음 한계를 넘어서는 번역 단위를 거부할 수 있어요:
| 내부 식별자 또는 매크로 이름의 유효 선행 문자 31개 · 외부 식별자의 유효 선행 문자 6개 · 하나의 번역 단위에 있는 외부 식별자 511개 · 한 블록에 선언된 블록 스코프 식별자 127개 · 하나의 전처리 번역 단위에 동시 정의된 매크로 식별자 1024개 | (C99 이전) |
|---|---|
| 내부 식별자 또는 매크로 이름의 유효 선행 문자 63개 · 외부 식별자의 유효 선행 문자 31개 · 하나의 번역 단위에 있는 외부 식별자 4095개 | (C99부터) |
더 알아보기
- 식별자가 어떤 대상을 가리키는지 규칙은
lookup and name spaces문서에서 확인할 수 있어요. - 식별자가 유효한 범위를 정하는 규칙은
scope문서를 함께 보면 좋아요.