Идентификатор
Идентификатор — это последовательность произвольной длины, состоящая из цифр, символов подчёркивания, строчных и прописных латинских букв, а также символов Unicode, указанных с помощью нотации экранирования \u и \U(начиная с C99), класса XID_Continue(начиная с C23). Допустимый идентификатор должен начинаться с символа, не являющегося цифрой (латинской буквы, символа подчёркивания или символа Unicode, не являющегося цифрой(начиная с C99)(до C23 включительно) или символа Unicode класса XID_Start)(начиная с 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) |
Идентификаторы могут обозначать следующие типы сущностей:
- объекты
- функции
- теги (структуры, объединения или перечисления)
- члены структуры или объединения
- константы перечисления
- имена typedef
- имена меток
- имена макросов
- имена параметров макросов
Каждый идентификатор, кроме имён макросов и параметров макросов, имеет область видимости, принадлежит пространству имён и может иметь связь. Один и тот же идентификатор может обозначать разные сущности в разных точках программы или разные сущности в одной точке, если сущности принадлежат разным пространствам имён.
Зарезервированные идентификаторы
Следующие идентификаторы зарезервированы и не могут объявляться в программе (такое объявление приводит к неопределённому поведению):
- Идентификаторы, являющиеся ключевыми словами, нельзя использовать для других целей. В частности, #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 Ограничения трансляции (стр.: 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++ для идентификаторов |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/c/language/identifier