Spec-Zone.ru › C

Идентификатор

Идентификатор — это последовательность произвольной длины, состоящая из цифр, символов подчёркивания, строчных и прописных латинских букв, а также символов 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
  • имена меток
  • имена макросов
  • имена параметров макросов

Каждый идентификатор, кроме имён макросов и параметров макросов, имеет область видимости, принадлежит пространству имён и может иметь связь. Один и тот же идентификатор может обозначать разные сущности в разных точках программы или разные сущности в одной точке, если сущности принадлежат разным пространствам имён.

Зарезервированные идентификаторы

Следующие идентификаторы зарезервированы и не могут объявляться в программе (такое объявление приводит к неопределённому поведению):

  1. Идентификаторы, являющиеся ключевыми словами, нельзя использовать для других целей. В частности, #define или #undef идентификатора, совпадающего с ключевым словом, не допускается.
  2. Все внешние идентификаторы, начинающиеся с символа подчёркивания.
  3. Все идентификаторы, начинающиеся с символа подчёркивания, за которым следует прописная буква или ещё один символ подчёркивания (эти зарезервированные идентификаторы позволяют библиотеке использовать множество внутренних макросов и функций, не имеющих внешней связи).
  4. Все внешние идентификаторы, определённые стандартной библиотекой (в среде с поддержкой размещённой реализации). Это означает, что пользовательские внешние имена не могут совпадать ни с одним именем библиотеки, даже если объявляется функция, совпадающая с функцией библиотеки.
  5. Идентификаторы, зарезервированные для реализации или будущего использования стандартной библиотекой (см. ниже).
  6. Идентификаторы, объявленные потенциально зарезервированными и предоставляемые реализацией (см. ниже). (начиная с 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 требует, чтобы любая соответствующая стандарту реализация поддерживала как минимум следующие ограничения:

  • 31 значимый начальный символ во внутреннем идентификаторе или имени макроса
  • 6 значимых начальных символов во внешнем идентификаторе
  • 511 внешних идентификаторов в одной единице трансляции
  • 127 идентификаторов с блочной областью видимости, объявленных в одном блоке
  • 1024 идентификатора макросов, одновременно определённых в одной единице трансляции препроцессора
(до C99 включительно)
  • 63 значимых начальных символа во внутреннем идентификаторе или имени макроса
  • 31 значимый начальный символ во внешнем идентификаторе
  • 4095 внешних идентификаторов в одной единице трансляции
  • 511 идентификаторов с блочной областью видимости, объявленных в одном блоке
  • 4095 идентификаторов макросов, одновременно определённых в одной единице трансляции препроцессора
(начиная с 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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API