标识符
标识符 是一个任意长度的数字、下划线、小写和大写拉丁字母序列,以及使用 \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 起) |
[编辑] 参考文献
- C23 标准 (ISO/IEC 9899:2024)
- 5.2.5.2 翻译限制 (页码: 待定)
- 6.4.2 标识符 (页码: 待定)
- 6.10.10 预定义宏名称 (页码: 待定)
- 6.11.7 预定义宏名称 (页码: 待定)
- 7.33 未来库方向 (页码: 待定)
- K.3.1.2 保留标识符 (页码: 待定)
- C17 标准 (ISO/IEC 9899:2018)
- 5.2.4.1 翻译限制 (页码: 19-20)
- 6.4.2 标识符 (页码: 43)
- 6.10.8 预定义宏名称 (页码: 127-129)
- 6.11.9 预定义宏名称 (页码: 130)
- 7.31 未来库方向 (页码: 332-333)
- K.3.1.2 保留标识符 (页码: 425)
- C11 标准 (ISO/IEC 9899:2011)
- 5.2.4.1 翻译限制 (页码: 25-26)
- 6.4.2 标识符 (页码: 59-60)
- 6.10.8 预定义宏名称 (页码: 175-176)
- 6.11.9 预定义宏名称 (页码: 179)
- 7.31 未来库方向 (页码: 455-457)
- K.3.1.2 保留标识符 (页码: 584)
- C99 标准 (ISO/IEC 9899:1999)
- 5.2.4.1 翻译限制 (页码: 20-21)
- 6.4.2 标识符 (页码: 51-52)
- 6.10.8 预定义宏名称 (页码: 160-161)
- 6.11.9 预定义宏名称 (页码: 163)
- 7.26 未来库方向 (页码: 401-402)
- C89/C90 标准 (ISO/IEC 9899:1990)
- 2.2.4.1 翻译限制
- 3.1.2 标识符
- 3.8.8 预定义宏名称
[编辑] 参见
C++ 文档 关于 标识符
|