标识符
标识符是一个任意长度的序列,由数字、下划线、大小写拉丁字母,以及使用 \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不同点可以表示不同的实体,或者如果实体位于不同的命名空间,则在同一个点也可以表示不同的实体。
目录 |
[编辑] 保留标识符
以下标识符是保留的,不得在程序中声明(这样做会导致未定义行为):
- 关键字标识符不能用于其他目的。特别是,不允许 #define 或 #undef 与关键字相同的标识符。
- 所有以下划线开头的外部标识符。
- 所有以下划线后跟大写字母或另一个下划线开头的标识符(这些保留标识符允许库使用许多幕后的非外部宏和函数)。
- 标准库(在托管环境中)定义的所有外部标识符。这意味着不允许用户提供的外部名称与任何库名称匹配,即使声明一个与库函数相同的函数也不允许。
- 标准库声明为实现或未来使用保留的标识符(见下文)。
- 声明为潜在保留并由实现提供的标识符(见下文)。 (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 起)- 以
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 起)
- 以
建议实现对潜在保留标识符的声明或定义发出警告,除非:
|
(自 C23 起) |
[编辑] 翻译限制
尽管标识符的长度没有特定的限制,但早期的编译器对标识符中有效起始字符的数量有限制,链接器对具有外部链接的名称施加了更严格的限制。C 要求任何符合标准的实现至少支持以下限制:
|
(直到 C99) |
|
(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++ 文档,关于标识符
|