标识符
一个标识符是一个任意长度的数字、下划线、小写和大写拉丁字母,以及使用 `\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) |
标识符可以表示以下类型的实体
除了宏名称或宏参数名称之外,每个标识符都有 范围,属于一个 命名空间,并且可能具有 链接。同一个标识符可以在程序的不同位置表示不同的实体,或者如果实体在不同的命名空间中,则可能在同一个位置表示不同的实体。
内容 |
[编辑] 保留标识符
以下标识符是保留的,不能在程序中声明(这样做会导致未定义的行为)
- 作为 关键字 的标识符不能用于其他目的。特别是,不允许对与关键字相同的标识符进行 #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) |
[编辑] 参考文献
- 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++ 文档 关于 标识符
|