Identifier
Идентификатор
— это произвольно длинная последовательность цифр, подчёркиваний, строчных и заглавных латинских букв
, а также Unicode-символов, задаваемых с помощью
\u
и
\U
escape-последовательностей
(начиная с C99)
, принадлежащих классу
XID_Continue
(начиная с C23)
. Корректный идентификатор должен начинаться с нецифрового символа (латинской буквы, подчёркивания
или Unicode-символа, не являющегося цифрой
(начиная с C99)
(до C23)
или Unicode-символа класса
XID_Start
)
(начиная с C23)
). Идентификаторы чувствительны к регистру (строчные и заглавные буквы различаются).
Каждый идентификатор должен соответствовать
Нормализованной форме C
.
(начиная с C23)
Определяется реализацией, разрешены ли необработанные (не экранированные) символы Юникода в идентификаторах:
char *\U0001f431 = "cat"; // поддерживается char *🐱 = "cat"; // определяется реализацией // (например, работает в Clang, но не в GCC до версии 10) // оба варианта некорректны в C23. Emoji не являются символами XID_Start |
(начиная с C99)
(до C23) |
| Определяемые реализацией символы, чьи соответствующие кодовые точки в ISO/IEC 10646 (Unicode) имеют свойство XID_Start или XID_Continue, могут появляться в начале или после первого символа идентификатора соответственно. | (начиная с C23) |
Идентификаторы могут обозначать следующие типы сущностей:
- объекты
- функции
- теги ( struct , union , или enumerations )
- члены структур или объединений
- константы перечислений
- typedef имена
- метки имён
- макросы имён
- параметры макросов имён
Каждый идентификатор, кроме имён макросов или имён параметров макросов, имеет область видимости , принадлежит к пространству имён и может обладать линковкой . Один и тот же идентификатор может обозначать разные сущности в разных точках программы или может обозначать разные сущности в одной и той же точке, если эти сущности находятся в разных пространствах имён.
Содержание |
Зарезервированные идентификаторы
Следующие идентификаторы являются зарезервированными и не могут быть объявлены в программе (это вызывает неопределённое поведение):
- Идентификаторы, которые являются ключевыми словами , не могут использоваться для других целей. В частности, не допускается #define или #undef идентификатора, совпадающего с ключевым словом.
- Все внешние идентификаторы, начинающиеся с подчеркивания.
- Все идентификаторы, начинающиеся с подчеркивания, за которым следует заглавная буква или другое подчеркивание (эти зарезервированные идентификаторы позволяют библиотеке использовать множество внутренних макросов и функций, не являющихся внешними).
- Все внешние идентификаторы, определенные стандартной библиотекой (в hosted environment). Это означает, что пользовательские внешние имена не должны совпадать с любыми именами из библиотеки, даже при объявлении функции, идентичной библиотечной.
- Идентификаторы, объявленные зарезервированными для реализации или будущего использования стандартной библиотекой (см. ниже).
- Идентификаторы, объявленные потенциально зарезервированными и предоставляемые реализацией (см. ниже). (since C23)
Все остальные идентификаторы доступны. Идентификаторы, которые не зарезервированы или потенциально не зарезервированы (since C23) могут использоваться без опасения непредвиденных конфликтов при переносе программ с одного компилятора и библиотеки на другой.
Примечание: в C++ идентификаторы с двойным подчеркиванием в любом месте зарезервированы везде; в C только те, которые начинаются с двойного подчеркивания, зарезервированы.
Зарезервированные и потенциально зарезервированные идентификаторы в библиотеке
Стандартная библиотека резервирует каждый предоставляемый ею идентификатор. Зарезервированные идентификаторы, имеющие внешнюю линковку (например, имена всех стандартных функций), зарезервированы независимо от того, какой заголовочный файл включен. Остальные зарезервированные идентификаторы резервируются при включении любого из связанных с ними заголовочных файлов.
|
Потенциально зарезервированные идентификаторы предназначены для использования реализацией и будущими версиями стандарта. Если потенциально зарезервированный идентификатор предоставляется реализацией, он становится зарезервированным. Реализациям разрешено предоставлять только внешние определения потенциально зарезервированных идентификаторов, которые зарезервированы как имена функций. Потенциально зарезервированные идентификаторы, не предоставляемые реализацией, не являются зарезервированными. Они могут быть объявлены или определены пользователем без неопределенного поведения. Однако такое использование не является переносимым. |
(since C23) |
Следующие идентификаторы зарезервированы или потенциально зарезервированы (since 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)
-
начинающиеся с
|
Рекомендуется, чтобы реализации выдавали предупреждение при объявлении или определении потенциально зарезервированных идентификаторов, за исключением случаев, когда
|
(since C23) |
Ограничения трансляции
Несмотря на отсутствие конкретных ограничений на длину идентификаторов, ранние компиляторы имели ограничения на количество значимых начальных символов в идентификаторах, а линкеры накладывали более строгие ограничения на имена с внешней линковкой . Требования языка C гарантируют, что любая соответствующая стандарту реализация поддерживает как минимум следующие ограничения:
|
(до C99) |
|
(начиная с C99) |
Ссылки
- Стандарт C23 (ISO/IEC 9899:2024):
-
- 5.2.5.2 Ограничения трансляции (стр.: TBD)
-
- 6.4.2 Идентификаторы (стр.: TBD)
-
- 6.10.10 Предопределенные имена макросов (стр.: TBD)
-
- 6.11.7 Предопределенные имена макросов (стр.: TBD)
-
- 7.33 Перспективные направления библиотеки (стр.: TBD)
-
- K.3.1.2 Зарезервированные идентификаторы (стр.: TBD)
- Стандарт 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++ documentation
для
Identifiers
|