名稱空間
變體
操作

識別符號

來自 cppreference.com
< c‎ | 語言

識別符號是一個任意長度的序列,由數字、下劃線、大小寫拉丁字母,以及使用 \u\U 轉義符號指定的 Unicode 字元(C99 起),屬於 XID_Continue(C23 起)組成。有效的識別符號必須以非數字字元(拉丁字母、下劃線,或 Unicode 非數字字元(C99 起)(C23 止),或屬於 XID_Start 類的 Unicode 字元(C23 起))開頭。識別符號區分大小寫(小寫字母和大寫字母是不同的)。每個識別符號都必須符合 規範化形式 C(C23 起)

是否允許在識別符號中使用原始(未轉義的)Unicode 字元是實現定義的。
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 起)

識別符號可以表示以下型別的實體:

除宏名稱或宏引數名稱外的每個識別符號都具有作用域,屬於一個名稱空間,並可能具有連結。同一個識別符號在程式的R不同點可以表示不同的實體,或者如果實體位於不同的名稱空間,則在同一個點也可以表示不同的實體。

目錄

[編輯] 保留識別符號

以下識別符號是保留的,不得在程式中宣告(這樣做會導致未定義行為):

  1. 關鍵字識別符號不能用於其他目的。特別是,不允許 #define 或 #undef 與關鍵字相同的識別符號。
  2. 所有以下劃線開頭的外部識別符號。
  3. 所有以下劃線後跟大寫字母或另一個下劃線開頭的識別符號(這些保留識別符號允許庫使用許多幕後的非外部宏和函式)。
  4. 標準庫(在託管環境中)定義的所有外部識別符號。這意味著不允許使用者提供的外部名稱與任何庫名稱匹配,即使宣告一個與庫函式相同的函式也不允許。
  5. 標準庫宣告為實現或未來使用保留的識別符號(見下文)。
  6. 宣告為潛在保留並由實現提供的識別符號(見下文)。 (C23 起)

所有其他識別符號均可用。未保留或潛在保留(C23 起)的識別符號可以放心使用,在程式從一個編譯器和庫遷移到另一個時,不會出現意外衝突。

注意:在 C++ 中,任何地方包含雙下劃線的識別符號都被保留;在 C 中,只有以雙下劃線開頭的識別符號被保留。

[編輯] 庫中保留和潛在保留的識別符號

標準庫保留其提供的所有識別符號。具有外部連結的保留識別符號(例如,每個標準函式的名稱)無論包含哪個標頭檔案都被保留。其他保留識別符號在其任何關聯標頭檔案被包含時才被保留。

潛在保留識別符號旨在供實現和標準的未來修訂使用。如果實現提供了潛在保留識別符號,則它將變為保留識別符號。

實現只允許提供宣告為函式名的潛在保留識別符號的外部定義

未由實現提供的潛在保留識別符號不被保留。使用者可以宣告或定義它們而不會導致未定義行為。但是,這種用法不具備可移植性。

(自 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 起)
    • isto 後跟一個小寫字母開頭,在 <ctype.h><wctype.h>(C95 起)
    • strwcs(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 起)
    • intuint 開頭並以 _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 起)
    • INTUINT 開頭並以 _MAX_MIN_WIDTH(C23 起)_C 結尾,在 <stdint.h>;這些識別符號是潛在保留的(C23 起) (C99 起)
    • PRISCN 後跟小寫字母或字母 X 開頭,在 <inttypes.h>;這些識別符號是潛在保留的(C23 起) (C99 起)
    • LC_ 後跟一個大寫字母開頭,在 <locale.h>
    • FP_ 後跟一個大寫字母開頭,在 <math.h> (C23 起)
    • MATH_ 後跟一個大寫字母開頭,在 <math.h> 中;這些識別符號是潛在保留的 (C23 起)
    • SIGSIG_ 後跟一個大寫字母開頭,在 <signal.h>
    • TIME_ 後跟一個大寫字母開頭,在 <time.h> (C11 起)
    • ATOMIC_ 後跟一個大寫字母開頭,在 <stdatomic.h>;這些識別符號是潛在保留的(C23 起) (C11 起)
  • 列舉常量,所有這些都是潛在保留的(C23 起)
    • memory_order_ 後跟一個小寫字母開頭,在 <stdatomic.h> (C11 起)
    • cnd_mtx_thrd_tss_ 後跟一個小寫字母開頭,在 <threads.h> (C11 起)

建議實現對潛在保留識別符號的宣告或定義發出警告,除非:

  • 該宣告是實現提供的具有外部連結識別符號的非定義宣告,並且
  • 宣告中使用的型別與定義中使用的型別相容
(自 C23 起)

[編輯] 翻譯限制

儘管識別符號的長度沒有特定的限制,但早期的編譯器對識別符號中有效起始字元的數量有限制,連結器對具有外部連結的名稱施加了更嚴格的限制。C 要求任何符合標準的實現至少支援以下限制:

  • 內部識別符號或宏名稱中 31 個有效起始字元
  • 外部識別符號中 6 個有效起始字元
  • 一個翻譯單元中 511 個外部識別符號
  • 一個塊中宣告 127 個塊作用域識別符號
  • 一個預處理翻譯單元中同時定義 1024 個宏識別符號
(直到 C99)
  • 內部識別符號或宏名稱中 63 個有效起始字元
  • 外部識別符號中 31 個有效起始字元
  • 一個翻譯單元中 4095 個外部識別符號
  • 一個塊中宣告 511 個塊作用域識別符號
  • 一個預處理翻譯單元中同時定義 4095 個宏識別符號
(C99 起)

[編輯] 參考

  • C23 標準 (ISO/IEC 9899:2024)
  • 5.2.5.2 翻譯限制(p:待定)
  • 6.4.2 識別符號(p:待定)
  • 6.10.10 預定義宏名稱(p:待定)
  • 6.11.7 預定義宏名稱(p:待定)
  • 7.33 未來庫方向(p:待定)
  • K.3.1.2 保留識別符號(p:待定)
  • 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++ 文件,關於識別符號