Namespaces
Variants

Identifier

From cppreference.net

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

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

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

Содержание

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

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

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

  • 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++ documentation для Identifiers