Namespaces
Variants

Identifier

From cppreference.net

식별자(identifier) 는 숫자, 밑줄, 라틴 문자 소문자 및 대문자로 구성된 임의의 길이를 가진 시퀀스입니다 , 그리고 \u \U 이스케이프 표기법을 사용하여 지정된 유니코드 문자들 (C99부터) , 그리고 XID_Continue 클래스의 유니코드 문자들 (C23부터) . 유효한 식별자는 숫자가 아닌 문자(라틴 문자, 밑줄 , 또는 유니코드 숫자-아님 문자 (C99부터) (C23 이전까지) , 또는 XID_Start 클래스의 유니코드 문자 ) (C23부터) )로 시작해야 합니다. 식별자는 대소문자를 구분합니다(소문자와 대문자는 서로 다릅니다). 모든 식별자는 정규화 형식 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까지)
ISO/IEC 10646 (Unicode)에서 해당 코드 포인트가 XID_Start 또는 XID_Continue 속성을 가지는 구현체 정의 문자는 각각 식별자의 시작 부분이나 첫 번째 문자 이후에 나타날 수 있습니다. (C23부터)

식별자는 다음과 같은 유형의 개체를 나타낼 수 있습니다:

매크로 이름이나 매크로 매개변수 이름을 제외한 모든 식별자는 scope 를 가지며, name space 에 속하고, linkage 를 가질 수 있습니다. 동일한 식별자는 프로그램의 다른 지점에서 서로 다른 개체를 나타낼 수 있으며, 개체들이 서로 다른 name space에 있는 경우 동일한 지점에서도 서로 다른 개체를 나타낼 수 있습니다.

목차

예약 식별자

다음 식별자는 예약어 로서 프로그램에서 선언할 수 없습니다(이를 선언할 경우 정의되지 않은 동작이 발생합니다):

  1. 키워드 인 식별자는 다른 용도로 사용할 수 없습니다. 특히 키워드와 동일한 식별자를 #define 또는 #undef 하는 것은 허용되지 않습니다.
  2. 밑줄로 시작하는 모든 외부 식별자.
  3. 밑줄 뒤에 대문자 또는 다른 밑줄이 오는 모든 식별자 (이러한 예약된 식별자는 라이브러리가 다양한 내부 비외부 매크로와 함수를 사용할 수 있도록 합니다).
  4. 표준 라이브러리에 의해 정의된 모든 외부 식별자 (호스팅 환경에서). 이는 사용자가 제공하는 외부 이름이 라이브러리 이름과 일치해서는 안 됨을 의미하며, 라이브러리 함수와 동일한 함수를 선언하는 경우에도 마찬가지입니다.
  5. 구현을 위해 또는 표준 라이브러리의 향후 사용을 위해 예약된 것으로 선언된 식별자 (아래 참조).
  6. 잠재적으로 예약되었으며 구현에 의해 제공되는 것으로 선언된 식별자 (아래 참조). (C23부터)

다른 모든 식별자는 사용 가능합니다. 예약되지 않은 식별자 또는 잠재적으로 예약되지 않은 식별자 (C23부터) 는 프로그램을 한 컴파일러와 라이브러리에서 다른 곳으로 이동할 때 예기치 않은 충돌에 대한 걱정 없이 사용할 수 있습니다.

참고: C++에서는 어디에서나 이중 밑줄이 포함된 식별자는 모든 곳에서 예약되어 있습니다. C에서는 이중 밑줄로 시작하는 식별자만 예약되어 있습니다.

라이브러리에서 예약된 및 잠재적으로 예약된 식별자

표준 라이브러리는 제공하는 모든 식별자를 예약합니다. 외부 링크 를 가지는 예약된 식별자(예: 모든 표준 함수 이름)는 어떤 헤더가 포함되든 관계없이 예약됩니다. 다른 예약된 식별자들은 관련 헤더 중 하나가 포함될 때 예약됩니다.

잠재적으로 예약된 식별자(potentially reserved identifiers)는 구현체와 표준의 향후 개정판에서 사용하기 위한 것입니다. 잠재적으로 예약된 식별자가 구현체에 의해 제공되는 경우, 해당 식별자는 예약된 식별자가 됩니다.

구현체는 함수 이름으로 예약된 잠재적으로 예약된 식별자의 외부 정의(external definitions) 만 제공할 수 있습니다.

구현체에 의해 제공되지 않는 잠재적으로 예약된 식별자는 예약되지 않습니다. 사용자는 이러한 식별자를 정의하거나 선언할 수 있으며, 이는 미정의 동작(undefined behavior)을 유발하지 않습니다. 그러나 이러한 사용법은 이식성이 없습니다.

(C23부터)

다음 식별자들은 구현체 또는 표준 라이브러리의 향후 사용을 위해 예약되어 있습니다 또는 잠재적으로 예약되어 있습니다 (C23부터) .

  • 함수 이름 , 모두 잠재적으로 예약됨 (C23부터)
    • 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 접미사 변형, <complex.h> (C99부터)
    • 시작하는 is 또는 to 뒤에 소문자가 오는, <ctype.h> <wctype.h> (C95부터)
    • 시작하는 str 또는 wcs (C23부터) 뒤에 소문자가 오는, <stdlib.h> <inttypes.h> (C23부터)
    • 시작하는 cr_ , <math.h> (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> ; 이러한 식별자는 잠재적으로 예약됨 (C23부터) (C99부터)
    • PRI 또는 SCN 으로 시작하고 소문자 또는 X 로 이어지는 매크로, <inttypes.h> ; 이러한 식별자는 잠재적으로 예약됨 (C23부터) (C99부터)
    • LC_ 로 시작하고 대문자로 이어지는 매크로, <locale.h>
    • FP_ 로 시작하고 대문자로 이어지는 매크로, <math.h> (C23부터)
    • MATH_ 로 시작하고 대문자로 이어지는 매크로, <math.h> ; 이러한 식별자는 잠재적으로 예약됨 (C23부터)
    • SIG 또는 SIG_ 로 시작하고 대문자로 이어지는 매크로, <signal.h>
    • TIME_ 로 시작하고 대문자로 이어지는 매크로, <time.h> (C11부터)
    • ATOMIC_ 로 시작하고 대문자로 이어지는 매크로, <stdatomic.h> ; 이러한 식별자는 잠재적으로 예약됨 (C23부터) (C11부터)
  • 열거형 상수 , 모두 잠재적으로 예약됨 (C23부터)
    • memory_order_ 로 시작하고 소문자가 뒤따르는 것, <stdatomic.h> 에서 (C11부터)
    • cnd_ , mtx_ , thrd_ 또는 tss_ 로 시작하고 소문자가 뒤따르는 것, <threads.h> 에서 (C11부터)

구현체는 잠재적으로 예약된 식별자의 선언이나 정의 시 경고를 발생시키는 것을 권장합니다. 단, 다음 경우는 제외합니다:

  • 해당 선언이 구현체가 제공하는 외부 연결을 가진 식별자의 비정의 선언(non-definition declaration)이며,
  • 선언에 사용된 타입이 정의에 사용된 타입과 호환되는 경우입니다.
(C23부터)

번역 한계

식별자의 길이에 대한 특정 제한은 없지만, 초기 컴파일러들은 식별자의 유효 초기 문자 수에 제한이 있었고 링커들은 external linkage 를 가진 이름들에 대해 더 엄격한 제한을 적용했습니다. C는 모든 표준 준수 구현이 최소한 다음 제한들을 지원할 것을 요구합니다:

  • 내부 식별자 또는 매크로 이름에서 유효한 초기 문자 31개
  • 외부 식별자에서 유효한 초기 문자 6개
  • 하나의 번역 단위에서 외부 식별자 511개
  • 하나의 블록에서 선언된 블록 범위 식별자 127개
  • 하나의 전처리 번역 단위에서 동시에 정의된 매크로 식별자 1024개
(C99 이전)
  • 내부 식별자 또는 매크로 이름에서 유효한 초기 문자 63개
  • 외부 식별자에서 유효한 초기 문자 31개
  • 하나의 번역 단위에서 외부 식별자 4095개
  • 하나의 블록에서 선언된 블록 범위 식별자 511개
  • 하나의 전처리 번역 단위에서 동시에 정의된 매크로 식별자 4095개
(C99 이후)

참고문헌

  • C23 표준 (ISO/IEC 9899:2024):
  • 5.2.5.2 번역 제한 (p: TBD)
  • 6.4.2 식별자 (p: TBD)
  • 6.10.10 미리 정의된 매크로 이름 (p: TBD)
  • 6.11.7 미리 정의된 매크로 이름 (p: TBD)
  • 7.33 향후 라이브러리 방향 (p: TBD)
  • K.3.1.2 예약된 식별자 (p: TBD)
  • C17 표준 (ISO/IEC 9899:2018):
  • 5.2.4.1 번역 한계 (p: 19-20)
  • 6.4.2 식별자 (p: 43)
  • 6.10.8 미리 정의된 매크로 이름 (p: 127-129)
  • 6.11.9 미리 정의된 매크로 이름 (p: 130)
  • 7.31 향후 라이브러리 방향 (p: 332-333)
  • K.3.1.2 예약된 식별자 (p: 425)
  • C11 표준 (ISO/IEC 9899:2011):
  • 5.2.4.1 번역 한계 (p: 25-26)
  • 6.4.2 식별자 (p: 59-60)
  • 6.10.8 미리 정의된 매크로 이름 (p: 175-176)
  • 6.11.9 미리 정의된 매크로 이름 (p: 179)
  • 7.31 향후 라이브러리 방향 (p: 455-457)
  • K.3.1.2 예약된 식별자 (p: 584)
  • C99 표준 (ISO/IEC 9899:1999):
  • 5.2.4.1 번역 제한 (p: 20-21)
  • 6.4.2 식별자 (p: 51-52)
  • 6.10.8 미리 정의된 매크로 이름 (p: 160-161)
  • 6.11.9 미리 정의된 매크로 이름 (p: 163)
  • 7.26 향후 라이브러리 방향 (p: 401-402)
  • C89/C90 표준 (ISO/IEC 9899:1990):
  • 2.2.4.1 번역 한계
  • 3.1.2 식별자
  • 3.8.8 미리 정의된 매크로 이름

참고 항목

C++ 문서 참조: 식별자