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)

Идентификаторы могут обозначать следующие типы сущностей:

  • объекты
  • функции
  • теги (структуры, объединения или перечисления)
  • члены структуры или объединения
  • константы перечисления
  • псевдонимы типов
  • метки
  • имена макросов
  • имена параметров макросов

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

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

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

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

Все остальные идентификаторы доступны. Идентификаторы, которые не являются зарезервированными или потенциально зарезервированными(с C23), могут использоваться без опасений непредвиденных коллизий при переносе программ с одного компилятора и библиотеки на другой.

Примечание: в C++, идентификаторы с двумя символами подчеркивания где-либо зарезервированы везде; в C зарезервированы только те, которые начинаются с двух символов подчеркивания.

Зарезервированные и потенциально зарезервированные идентификаторы в библиотеке

Стандартная библиотека резервирует каждый предоставляемый ею идентификатор. Зарезервированные идентификаторы, которые имеют внешнюю связь (например, имя каждой стандартной функции), зарезервированы независимо от того, какой заголовок включён. Другие зарезервированные идентификаторы зарезервированы, когда включён любой из связанных с ними заголовков.

Потенциально зарезервированные идентификаторы предназначены для использования реализацией и будущими пересмотрами стандарта. Если потенциально зарезервированный идентификатор предоставляется реализацией, он становится зарезервированным.

Реализации разрешено предоставлять внешние определения потенциально зарезервированных идентификаторов, которые зарезервированы как имена функций.

Потенциально зарезервированные идентификаторы, которые не предоставляются реализацией, не зарезервированы. Пользователь может объявлять или определять их без неопределённого поведения. Однако такое использование не является переносимым.

(с C23)

Следующие идентификаторы зарезервированы или потенциально зарезервированы(с C23) для реализации или будущего использования стандартной библиотекой.

END_OF_DOCUMENT_MARKER
  • Имена функций, все из которых потенциально зарезервированы(с 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)

Ссылки

  • Стандарт 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/w/c/language/identifier

Spec-Zone.ru

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