Текст программы хранится в единицах, называемых source files в этом международном стандарте. Исходный файл вместе со всеми headers и исходными файлами included через директиву предварительной обработки #include, за исключением строк исходного кода, пропущенных какой-либо из conditional inclusion директив предварительной обработки, называется файлом translation unit. [ Note: Программу на C ++ не обязательно переводить одновременно. ] — end note
[ Note: Ранее переведенные единицы перевода и единицы создания экземпляров могут быть сохранены индивидуально или в библиотеках. Отдельные единицы трансляции программы передают ([basic.link]) посредством (например) вызовов функций, идентификаторы которых имеют внешнюю связь, манипулирования объектами, идентификаторы которых имеют внешнюю связь, или манипулирования файлами данных. Единицы перевода можно переводить отдельно, а затем linked создавать исполняемую программу. ] — end note
Приоритет синтаксических правил перевода определяется следующими этапами.12
1.Физические символы исходного файла сопоставляются, определяемым реализацией способом, с базовым набором исходных символов (вводя символы новой строки для индикаторов конца строки), если это необходимо. Допустимый набор символов физического исходного файла определяется реализацией. Любой символ исходного файла, не входящий в число basic source character set , заменяется символом, обозначающим этот символ. Реализация может использовать любую внутреннюю кодировку при условии, что фактический расширенный символ, встречающийся в исходном файле, и тот же расширенный символ, выраженный в исходном файле как (например, с использованием обозначения), обрабатываются эквивалентно, за исключением случаев, когда эта замена отменяется. ( ) в необработанном строковом литерале.universal-character-nameuniversal-character-name \uXXXX [lex.pptoken]
2.Каждый экземпляр символа обратной косой черты (\), за которым сразу следует символ новой строки, удаляется, сращивая физические исходные строки для формирования логических исходных строк. Только последняя обратная косая черта на любой физической исходной строке должна иметь право быть частью такого соединения. За исключением соединений, возвращенных в необработанный строковый литерал, если в результате соединения получается последовательность символов, соответствующая синтаксису a universal-character-name, поведение не определено. Исходный файл, который не является пустым и который не заканчивается символом новой строки или который заканчивается символом новой строки, которому непосредственно предшествует символ обратной косой черты до того, как произойдет какое-либо такое объединение, должен обрабатываться, как если бы дополнительный новый- строчный символ был добавлен к файлу.
3.Исходный файл разбивается на preprocessing tokens последовательности символов пробела (включая комментарии). Исходный файл не должен заканчиваться токеном частичной предварительной обработки или частичным комментарием.13 Каждый комментарий заменяется одним пробелом. Символы новой строки сохраняются. Сохраняется ли каждая непустая последовательность символов пробела, отличная от новой строки, или заменяется одним символом пробела, не определено. Процесс разделения символов исходного файла на токены предварительной обработки зависит от контекста. [ Example: см. обработку < в #include директиве предварительной обработки. ] — end example
4.Выполняются директивы предварительной обработки, расширяются вызовы макросов и выполняются _Pragma унарные операторные выражения. Если последовательность символов, соответствующая синтаксису a universal-character-name, создается с помощью token concatenation, поведение не определено. #include Предобработки директива вызывает указанный файл заголовок или источник для обработки от фазы 1 до фазы 4, рекурсивен. Затем все директивы предварительной обработки удаляются.
5.Каждый член исходного набора символов в символьном литерале или строковом литерале, а также каждая escape-последовательность и universal-character-nameв символьном литерале или необработанном строковом литерале преобразуется в соответствующий член набора символов выполнения ([lex.ccon], [lex.string]); если нет соответствующего члена, он преобразуется в определяемый реализацией член, отличный от нулевого (широкого) символа.14
6.Смежные лексемы строковых литералов объединяются.
7.Символы пробела, разделяющие токены, больше не имеют значения. Каждый токен предварительной обработки преобразуется в token. Полученные токены синтаксически и семантически анализируются и переводятся как единица перевода. [ Note: Процесс анализа и перевода токенов может иногда приводить к замене одного токена последовательностью других токенов ([temp.names]). ] [ Исходные файлы, единицы перевода и переведенные единицы перевода не обязательно должны храниться в виде файлов, и нет необходимости иметь какое-либо однозначное соответствие между этими объектами и любым внешним представлением. Описание носит только концептуальный характер и не указывает конкретную реализацию. ] — end note Note: — end note
8.Переведенные единицы перевода и единицы создания экземпляров объединяются следующим образом: [ Note: Некоторые или все из них могут быть предоставлены из библиотеки. ] Каждая переведенная единица перевода проверяется, чтобы составить список требуемых экземпляров. [ Это может включать экземпляры, которые были . ] Определения необходимых шаблонов находятся. Это определяется реализация, требуется ли источник перевода единиц , содержащих эти определения должны быть доступны. [ Реализация могла бы закодировать достаточную информацию в переведенной единице перевода, чтобы гарантировать, что источник здесь не требуется. ] Все необходимые экземпляры выполняются для создания . [ Они похожи на переведенные единицы перевода, но не содержат ссылок на неустановленные шаблоны и не содержат определений шаблонов. ] Программа плохо сформирована, если какой-либо экземпляр не удается. — end note Note: explicitly requested — end note Note: — end note instantiation units Note: — end note
9.Все ссылки на внешние сущности разрешены. Компоненты библиотеки связаны для соответствия внешним ссылкам на объекты, не определенные в текущем переводе. Весь такой вывод транслятора собирается в образ программы, который содержит информацию, необходимую для выполнения в среде выполнения.
Реализации должны вести себя так, как если бы происходили эти отдельные фазы, хотя на практике разные фазы могут быть объединены.
Токен частичной предварительной обработки может возникнуть из исходного файла, заканчивающегося первой частью многосимвольного токена, для которого требуется завершающая последовательность символов, например a, в header-name котором отсутствует закрывающее " или >. Частичный комментарий может возникнуть из исходного файла, заканчивающегося незакрытым /* комментарием.
Реализации не требуется преобразовывать все несоответствующие исходные символы в один и тот же символ выполнения.
Он basic source character set состоит из 96 символов: пробела, управляющих символов, представляющих горизонтальную табуляцию, вертикальную табуляцию, подачу страницы и новую строку, а также следующие 91 графический символ:15
a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 _ { } [ ] # ( ) < > % : ; . ? * + - / ^ & | ~ ! = , \ " '
Эта universal-character-nameконструкция позволяет давать имена другим персонажам.
hex-quad: hexadecimal-digit hexadecimal-digit hexadecimal-digit hexadecimal-digit
universal-character-name: \u hex-quad \U hex-quad hex-quad
Характер обозначены теми universal-character-name \UNNNNNNNN , что персонаж, характер которого сокращенное наименование в ИСО / МЭК 10646 является NNNNNNNN; символ, обозначенный знаком, universal-character-name \uNNNN является тем символом, которому соответствует короткое имя символа в ISO / IEC 10646 0000NNNN. Если шестнадцатеричное значение для a universal-character-nameсоответствует суррогатной кодовой точке (в диапазоне 0xD800–0xDFFF включительно), программа имеет неправильный формат. Кроме того, если шестнадцатеричное значение для universal-character-nameСнаружи c-char-sequence, s-char-sequenceили r-char-sequenceиз символа или строк литералов соответствуют управляющему символу (в любом из диапазонов 0x00-0x1F или 0x7F-0x9F, оба включительно) или к символу в основном исходном характере установлен, программа сформирована неправильно.16
Каждый из basic execution character set и basic execution wide-character set должен содержать все элементы базового исходного набора символов плюс управляющие символы, представляющие предупреждение, возврат и возврат каретки, плюс null character (соответственно null wide character), значение которого равно 0. Для каждого базового набора символов выполнения значения члены должны быть неотрицательными и отличными друг от друга. Как в исходном, так и в исполнительном базовых наборах символов значение каждого символа после 0 в приведенном выше списке десятичных цифр должно быть на единицу больше, чем значение предыдущего. execution character set И execution wide-character set являются осуществлением определенных надмножеств базового набора символов и выполнения основного набора выполнения широких символов, соответственно. Значения элементов наборов символов выполнения и наборов дополнительных элементов зависят от локали.
Глифы для элементов основного исходного набора символов предназначены для идентификации символов из подмножества ISO / IEC 10646, которое соответствует набору символов ASCII. Однако, поскольку отображение символов исходного файла в исходный набор символов (описанное в фазе перевода 1) задано как определяемое реализацией, требуется реализация, чтобы задокументировать, как основные исходные символы представлены в исходных файлах.
Последовательность символов, напоминающая a universal-character-nameв a r-char-sequence, не образует a universal-character-name.
preprocessing-token: header-name identifier pp-number character-literal user-defined-character-literal string-literal user-defined-string-literal preprocessing-op-or-punc each non-white-space character that cannot be one of the above
Каждый токен предварительной обработки, преобразованный в a, token должен иметь лексическую форму ключевого слова, идентификатора, литерала, оператора или пунктуатора.
Токен предварительной обработки - это минимальный лексический элемент языка на этапах преобразования с 3 по 6. Категории токена предварительной обработки: имена заголовков, идентификаторы, числа предварительной обработки, символьные литералы (включая определяемые пользователем символьные литералы), строковые литералы (включая пользовательские литералы). определенные строковые литералы), операторы предварительной обработки и знаки препинания, а также отдельные символы без пробелов, которые лексически не соответствуют другим категориям токенов предварительной обработки. Если символ ' или " соответствует последней категории, поведение не определено. Токены предварительной обработки могут быть разделены пробелом; он состоит из commentsсимволов или пробелов (пробел, горизонтальная табуляция, новая строка, вертикальная табуляция и перевод страницы), или и того, и другого. Как описано в пункте [cpp], в определенных обстоятельствах во время фазы трансляции 4 пробелы (или их отсутствие) служат чем-то большим, чем разделение токенов предварительной обработки. Пробел может появляться в токене предварительной обработки только как часть имени заголовка или между кавычками в символьном литерале или строковом литерале.
Если входной поток был проанализирован на токены предварительной обработки до заданного символа:
Если следующий символ начинает последовательность символов, которая может быть префиксом и начальной двойной кавычкой необработанного строкового литерала, например R", следующий токен предварительной обработки должен быть необработанным строковым литералом. Между начальным и конечным символами двойных кавычек необработанной строки любые преобразования, выполненные на этапах 1 и 2 ( universal-character-names и сращивание строк), отменяются; это обращение применяется до того d-char, как r-charбудут идентифицированы какие- либо ограничивающие скобки, или. Необработанный строковый литерал определяется как кратчайшая последовательность символов, соответствующая шаблону необработанной строки.
encoding-prefixopt R raw-string
В противном случае, если следующие три символа <:: и последующий символ не является ни : ни >, то < рассматривается как предварительная обработкой маркера самого по себе , а не в качестве первого символа альтернативных маркеров <:.
В противном случае следующий токен предварительной обработки - это самая длинная последовательность символов, которая может составлять токен предварительной обработки, даже если это приведет к сбою дальнейшего лексического анализа, за исключением того, что a header-nameформируется только внутри a #include directive.
[ Example:
#define R "x"
const char* s = R"y"; // ill-formed raw string, not "x" "y"
— end example ]
[ Example: Фрагмент программы 0xe+foo анализируются как предварительная обработкой числа лексем (тот , который не является допустимым с плавающим или целым числом буквальных маркеров), даже несмотря на то синтаксическим анализ в виде три Препроцессирования маркеров 0xe, +и foo может произвести корректное выражение (например, если foo были определены макро как 1). Точно так же фрагмент программы 1E1 анализируется как номер предварительной обработки (тот, который является допустимым плавающим литеральным токеном), независимо от того, E является ли это именем макроса. ] — end example
Для некоторых операторов и знаков препинания предусмотрены альтернативные представления токенов.17
Во всех отношениях языка каждый альтернативный токен ведет себя, соответственно, так же, как его основной токен, за исключением его написания.18 Набор альтернативных токенов определен в таблице 1.
Альтернатива | Начальный | Альтернатива | Начальный | Альтернатива | Начальный |
<% | { | and | && | and_eq | &= |
%> | } | bitor | | | or_eq | |= |
<: | [ | or | || | xor_eq | ^= |
:> | ] | xor | ^ | not | ! |
%: | # | compl | ~ | not_eq | != |
%:%: | ## | bitand | & |
К ним относятся «орграфы» и дополнительные зарезервированные слова. Термин «орграф» (токен, состоящий из двух символов) не является полностью описательным, поскольку один из альтернативных токенов предварительной обработки %:%: и, конечно же, несколько основных токенов содержат два символа. Тем не менее, те альтернативные токены, которые не являются лексическими ключевыми словами, в просторечии известны как «диграфы».
Таким образом, “stringized” значения [ и <: будут разными при сохранении исходного написания, но в противном случае токены можно свободно менять местами.
token: identifier keyword literal operator punctuator
Есть пять видов токенов: идентификаторы, ключевые слова, литералы,19 операторы и другие разделители. Пробелы, горизонтальные и вертикальные табуляции, новые строки, переводы форм и комментарии (вместе «пробелы»), как описано ниже, игнорируются, за исключением тех случаев, когда они служат для разделения токенов. [ Note: Некоторый пробел требуется для разделения смежных идентификаторов, ключевых слов, числовых литералов и альтернативных токенов, содержащих буквенные символы. ] — end note
Литералы включают строки, символьные и числовые литералы.
Персонажи /* начинают комментарий, который заканчивается символами */. Эти комментарии не гнездятся. Символы // начинают комментарий, который заканчивается непосредственно перед следующим символом новой строки. Если в таком комментарии есть символ перевода страницы или вертикальной табуляции, между ним и новой строкой, завершающей комментарий, должны появляться только символы пробела; Диагностика не требуется. [ Note: Комментарий символов //, /*и */ не имеют особого значения в пределах // комментария и обрабатываются так же , как другие символы. Точно так же символы // и не /* имеют особого значения внутри /* комментария. ] — end note
header-name: < h-char-sequence > " q-char-sequence "
h-char-sequence: h-char h-char-sequence h-char
h-char: any member of the source character set except new-line and >
q-char-sequence: q-char q-char-sequence q-char
q-char: any member of the source character set except new-line and "
[ Note: Токены предварительной обработки имени заголовка появляются только в #include директиве предварительной обработки (см. [lex.pptoken]). ] Последовательности в обеих формах отображаются способом, определяемым реализацией, в заголовки или имена внешних исходных файлов, как указано в . — end note header-names [cpp.include]
Появление любого из символов, ' или \ любой из последовательностей символов, /* или // в, q-char-sequenceили в h-char-sequence условно поддерживается семантикой, определяемой реализацией, как и внешний вид символа " в h-char-sequence.20
Таким образом, последовательность символов, напоминающая escape-последовательность, может привести к ошибке, быть интерпретирована как символ, соответствующий escape-последовательности, или иметь совершенно другое значение, в зависимости от реализации.
pp-number: digit . digit pp-number digit pp-number identifier-nondigit pp-number ' digit pp-number ' nondigit pp-number e sign pp-number E sign pp-number p sign pp-number P sign pp-number .
Предварительная обработка числовых токенов лексически включает все integer literal токены и все floating literal токены.
identifier: identifier-nondigit identifier identifier-nondigit identifier digit
identifier-nondigit: nondigit universal-character-name
nondigit: one of a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _
digit: one of 0 1 2 3 4 5 6 7 8 9
Идентификатор - это произвольно длинная последовательность букв и цифр. Каждый universal-character-nameв идентификаторе должен обозначать символ, кодировка которого в ISO 10646 попадает в один из диапазонов, указанных в таблице 2. Начальный элемент не должен быть universal-character-name обозначением символа, кодировка которого попадает в один из диапазонов, указанных в таблице 3. Прописные и строчные буквы различаются. Все персонажи значительны.21
00A8 | 00AA | 00AD | 00AF | 00B2-00B5 |
00B7-00BA | 00BC-00BE | 00C0-00D6 | 00D8-00F6 | 00F8-00FF |
0100-167F | 1681-180D | 180F-1FFF | ||
200B-200D | 202A-202E | 203F-2040 | 2054 | 2060-206F |
2070-218F | 2460-24FF | 2776-2793 | 2C00-2DFF | 2E80-2FFF |
3004-3007 | 3021-302F | 3031-D7FF | ||
F900-FD3D | FD40-FDCF | FDF0-FE44 | FE47-FFFD | |
10000-1FFFD | 20000-2FFFD | 30000-3FFFD | 40000-4FFFD | 50000-5FFFD |
60000-6FFFD | 70000-7FFFD | 80000-8FFFD | 90000-9FFFD | A0000-AFFFD |
B0000-BFFFD | C0000-CFFFD | D0000-DFFFD | E0000-EFFFD |
0300-036F | 1DC0-1DFF | 20D0-20FF | FE20-FE2F |
Идентификаторы в таблице 4 имеют особое значение при появлении в определенном контексте. Когда они упоминаются в грамматике, эти идентификаторы используются явно, а не с использованием identifierграмматической продукции. Если не указано иное, любая двусмысленность относительно того, identifierимеет ли данное значение особое значение, разрешается интерпретировать токен как обычный identifier.
Кроме того, некоторые идентификаторы зарезервированы для использования реализациями C ++ и не должны использоваться иначе; Диагностика не требуется.
Каждый идентификатор, содержащий двойное подчеркивание или начинающийся с подчеркивания, за которым следует заглавная буква , зарезервирован для реализации для любого использования. __
Каждый идентификатор, начинающийся с подчеркивания, зарезервирован для реализации для использования в качестве имени в глобальном пространстве имен.
В системах, в которых компоновщики не могут принимать расширенные символы, для universal-character-nameформирования допустимых внешних идентификаторов может использоваться кодировка . Например, для кодирования \u в файле universal-character-name. Расширенные символы могут создавать длинный внешний идентификатор, но C ++ не устанавливает ограничения на перевод значимых символов для внешних идентификаторов. В C ++ буквы верхнего и нижнего регистра считаются разными для всех идентификаторов, включая внешние идентификаторы.
Идентификаторы, показанные в таблице 5 , зарезервированы для использования в качестве ключевых слов (то есть они безусловно рассматриваются как ключевые слова на этапе 7), за исключением attribute-token:
alignas | continue | friend | register | true |
alignof | decltype | goto | reinterpret_cast | try |
asm | default | if | return | typedef |
auto | delete | inline | short | typeid |
bool | do | int | signed | typename |
break | double | long | sizeof | union |
case | dynamic_cast | mutable | static | unsigned |
catch | else | namespace | static_assert | using |
char | enum | new | static_cast | virtual |
char16_t | explicit | noexcept | struct | void |
char32_t | export | nullptr | switch | volatile |
class | extern | operator | template | wchar_t |
const | false | private | this | while |
constexpr | float | protected | thread_local | |
const_cast | for | public | throw |
[ И ключевые слова не используются , но зарезервированы для использования в будущем. ] Note: export register — end note
Кроме того, альтернативные представления, показанные в таблице 6 для некоторых операторов и знаков препинания ([lex.digraph]), зарезервированы и не могут использоваться иначе:
and | and_eq | bitand | bitor | compl | not |
not_eq | or | or_eq | xor | xor_eq |
Лексическое представление программ C ++ включает ряд токенов предварительной обработки, которые используются в синтаксисе препроцессора или преобразуются в токены для операторов и знаков препинания:
preprocessing-op-or-punc: one of { } [ ] # ## ( ) <: :> <% %> %: %:%: ; : ... new delete ? :: . .* + - * / % ^ & | ~ ! = < > += -= *= /= %= ^= &= |= << >> >>= <<= == != <= >= && || ++ -- , ->* -> and and_eq bitand bitor compl not not_eq or or_eq xor xor_eq
Каждый preprocessing-op-or-puncконвертируется в один токен формата translation phase 7.
Есть несколько видов литералов.22
literal: integer-literal character-literal floating-literal string-literal boolean-literal pointer-literal user-defined-literal
Термин «буквальный» в данном международном стандарте обычно обозначает те токены, которые называются «константами» в ISO C.
integer-literal: binary-literal integer-suffixopt octal-literal integer-suffixopt decimal-literal integer-suffixopt hexadecimal-literal integer-suffixopt
binary-literal: 0b binary-digit 0B binary-digit binary-literal 'opt binary-digit
octal-literal: 0 octal-literal 'opt octal-digit
decimal-literal: nonzero-digit decimal-literal 'opt digit
hexadecimal-literal: hexadecimal-prefix hexadecimal-digit-sequence
binary-digit: 0 1
octal-digit: one of 0 1 2 3 4 5 6 7
nonzero-digit: one of 1 2 3 4 5 6 7 8 9
hexadecimal-prefix: one of 0x 0X
hexadecimal-digit-sequence: hexadecimal-digit hexadecimal-digit-sequence 'opt hexadecimal-digit
hexadecimal-digit: one of 0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F
integer-suffix: unsigned-suffix long-suffixopt unsigned-suffix long-long-suffixopt long-suffix unsigned-suffixopt long-long-suffix unsigned-suffixopt
unsigned-suffix: one of u U
long-suffix: one of l L
long-long-suffix: one of ll LL
An integer literal - это последовательность цифр, не имеющая точки или экспоненты, с необязательными разделяющими одинарными кавычками, которые игнорируются при определении ее значения. Целочисленный литерал может иметь префикс, определяющий его основу, и суффикс, определяющий его тип. Лексически первая цифра последовательности цифр является наиболее значимой. A binary integer literal (с основанием два) начинается с 0b или 0B и состоит из последовательности двоичных цифр. octal integer literal (База восемь) начинается с цифрой 0 и состоит из последовательности восьмеричных цифр.23 A decimal integer literal (основание десять) начинается с цифры, отличной от 0 и состоит из последовательности десятичных цифр. hexadecimal integer literal (Основание шестнадцать) начинается с 0x или 0X и состоит из последовательности шестнадцатеричных цифр, которые включают в себя десятичные цифры и буквы a пути f и A через F с десятичными значениями десять через пятнадцать. [ Example: Число двенадцать может быть записано 12, 014, 0XC, или 0b1100. Целочисленные литералы 1048576, 1'048'576, 0X100000, 0x10'0000, и 0'004'000'000 все они имеют одинаковое значение. ] — end example
Тип целочисленного литерала - это первый из соответствующего списка в таблице, 7 в котором может быть представлено его значение.
Суффикс | Десятичный литерал | Двоичный, восьмеричный или шестнадцатеричный литерал |
никто | int | int |
long int | unsigned int | |
long long int | long int | |
unsigned long int | ||
long long int | ||
unsigned long long int | ||
u или U | unsigned int | unsigned int |
unsigned long int | unsigned long int | |
unsigned long long int | unsigned long long int | |
l или L | long int | long int |
long long int | unsigned long int | |
long long int | ||
unsigned long long int | ||
Оба u или U | unsigned long int | unsigned long int |
и l или L | unsigned long long int | unsigned long long int |
ll или LL | long long int | long long int |
unsigned long long int | ||
Оба u или U | unsigned long long int | unsigned long long int |
и ll или LL |
Если целочисленный литерал не может быть представлен каким-либо типом в своем списке, а extended integer type может представлять его значение, он может иметь этот расширенный целочисленный тип. Если все типы в списке для целочисленного литерала подписаны, расширенный целочисленный тип должен быть подписан. Если все типы в списке для целочисленного литерала беззнаковые, расширенный целочисленный тип должен быть беззнаковым. Если список содержит как знаковые, так и беззнаковые типы, расширенный целочисленный тип может быть знаковым или беззнаковым. Программа плохо сформирована, если одна из ее единиц трансляции содержит целочисленный литерал, который не может быть представлен ни одним из разрешенных типов.
Цифры 8 и 9 не являются восьмеричными цифрами.
character-literal: encoding-prefixopt ' c-char-sequence '
encoding-prefix: one of u8 u U L
c-char-sequence: c-char c-char-sequence c-char
c-char: any member of the source character set except the single-quote ', backslash \, or new-line character escape-sequence universal-character-name
escape-sequence: simple-escape-sequence octal-escape-sequence hexadecimal-escape-sequence
simple-escape-sequence: one of \' \" \? \\ \a \b \f \n \r \t \v
octal-escape-sequence: \ octal-digit \ octal-digit octal-digit \ octal-digit octal-digit octal-digit
hexadecimal-escape-sequence: \x hexadecimal-digit hexadecimal-escape-sequence hexadecimal-digit
Символьный литерал представляет собой один или несколько символов , заключенные в одинарные кавычки, как и в 'x', необязательно предшествует u8, u, U, или L, как в u8'w', u'x', U'y', или L'z', соответственно.
Символьный литерал , который не начинается с u8, u, Uили L это ordinary character literal. Обычный символьный литерал, содержащий единственный c-charпредставимый в наборе символов выполнения, имеет тип charсо значением, равным числовому значению кодировки c-charв наборе символов выполнения. Обычный символьный литерал, содержащий более одного, c-char- это multicharacter literal. Multicharacter буквальный, или обычные символьный литерал , содержащий один c-charне представимы в наборе символов исполнения, условно-поддерживаются, имеет тип int, и имеет определенную реализацию значения.
Символьный литерал, начинающийся с u8, например u8'w', является символьным литералом типа char, известного как UTF-8 character literal. Значение символьного литерала UTF-8 равно его значению кодовой точки ISO 10646 при условии, что значение кодовой точки может быть представлено одной единицей кода UTF-8 (то есть при условии, что оно находится в элементах управления C0 и базовом латинском Unicode. блокировать). Если значение не может быть представлено одной единицей кода UTF-8, программа имеет неправильный формат. Символьный литерал UTF-8, содержащий несколько, c-chars имеет неправильный формат.
Символьный литерал, начинающийся с буквы u, например u'x', является символьным литералом типа char16_t. Значение char16_t символьного литерала, содержащего один c-char, равно его значению кодовой точки ISO 10646 при условии, что кодовая точка может быть представлена одной 16-битной кодовой единицей. (То есть при условии, что это базовая кодовая точка многоязычной плоскости.) Если значение не может быть представлено в пределах 16 бит, программа сформирована неправильно. char16_t Литера , содержащие несколько c-chars плохо сформировано.
Символьный литерал, начинающийся с буквы U, например U'y', является символьным литералом типа char32_t. Значение char32_t символьного литерала, содержащего один c-char, равно его значению кодовой точки ISO 10646. char32_t Литера , содержащие несколько c-chars плохо сформировано.
Символьный литерал, начинающийся с буквы L, например L'z', - это wide-character literal. Литерал с широкими символами имеет тип wchar_t.24 Значение литерала расширенных символов, содержащего один, c-charимеет значение, равное числовому значению кодировки c-charв наборе расширенных символов выполнения, если только c-charне имеет представления в наборе расширенных символов выполнения, и в этом случае значение равно определяется реализацией. [ Note: Тип wchar_t может представлять все элементы расширенного набора символов выполнения (см. [basic.fundamental]). ] Значение литерала для широких символов, содержащего несколько, определяется реализацией. — end note c-chars
Некоторые неграфические символы, одиночная кавычка ', двойные кавычки ", вопросительный знак ?,25 и обратный слэш \, могут быть представлены в соответствии с таблицей 8. Двойные кавычки " и вопросительный знак ?могут быть представлены сами по себе или с помощью управляющих последовательностей \" и \? соответственно, но одинарная кавычка ' и обратная косая черта \ должны быть представлены управляющими последовательностями \' и \\ соответственно. Управляющие последовательности, в которых символ, следующий за обратной косой чертой, не указан в таблице 8 , поддерживаются условно с семантикой, определяемой реализацией. Управляющая последовательность определяет один символ.
новая линия | NL (LF) | \n |
горизонтальная табуляция | HT | \t |
вертикальная табуляция | VT | \v |
Backspace | BS | \b |
возврат каретки | CR | \r |
подача формы | FF | \f |
тревога | BEL | \a |
обратная косая черта | \ | \\ |
вопросительный знак | ? | \? |
одинарная кавычка | ' | \' |
двойная кавычка | " | \" |
восьмеричное число | ооо | \ooo |
шестнадцатеричный номер | ххх | \xhhh |
Escape \ooo состоит из обратной косой черты, за которой следуют одна, две или три восьмеричных цифры, которые используются для указания значения желаемого символа. Escape \xhhh состоит из обратной косой черты, за которой x следует одна или несколько шестнадцатеричных цифр, которые используются для указания значения желаемого символа. Количество цифр в шестнадцатеричной последовательности не ограничено. Последовательность восьмеричных или шестнадцатеричных цифр завершается первым символом, который не является восьмеричной или шестнадцатеричной цифрой соответственно. Значение символьного литерала определяется реализацией, если оно выходит за пределы определенного реализацией диапазона, определенного для char (для символьных литералов без префикса) или wchar_t (для символьных литералов с префиксом L). [ Note: Если значение символа буквального префикса u, u8или U находится вне диапазона , определенный для его типа, программа плохо сформировано. ] — end note
A universal-character-nameпереводится в кодировку указанного символа в соответствующем наборе символов выполнения. Если такой кодировки нет, universal-character-nameпреобразуется в кодировку, определяемую реализацией. [ Note: На этапе перевода 1 universal-character-nameсимвол a вводится всякий раз, когда в исходном тексте встречается фактический расширенный символ. Поэтому все расширенные символы описываются в терминах universal-character-names. Однако фактическая реализация компилятора может использовать свой собственный набор символов, если будут получены те же результаты. ] — end note
Они предназначены для наборов символов, в которых символ не помещается в один байт.
Использование escape-последовательности для вопросительного знака поддерживается для совместимости с ISO C ++ 2014 и ISO C.
floating-literal: decimal-floating-literal hexadecimal-floating-literal
decimal-floating-literal: fractional-constant exponent-partopt floating-suffixopt digit-sequence exponent-part floating-suffixopt
hexadecimal-floating-literal: hexadecimal-prefix hexadecimal-fractional-constant binary-exponent-part floating-suffixopt hexadecimal-prefix hexadecimal-digit-sequence binary-exponent-part floating-suffixopt
fractional-constant: digit-sequenceopt . digit-sequence digit-sequence .
hexadecimal-fractional-constant: hexadecimal-digit-sequenceopt . hexadecimal-digit-sequence hexadecimal-digit-sequence .
exponent-part: e signopt digit-sequence E signopt digit-sequence
binary-exponent-part: p signopt digit-sequence P signopt digit-sequence
sign: one of + -
digit-sequence: digit digit-sequence 'opt digit
floating-suffix: one of f l F L
Плавающий буквальным состоит из необязательного префикса указав основание, целую часть, точку базисной, фракцию , часть, в , , или , необязательно целочисленный показатель степень, и необязательный суффикс типа. Целая и дробная части состоят из последовательности десятичных (основание десять) цифр, если нет префикса, или шестнадцатеричных (основание шестнадцати) цифр, если префиксом является или . Плавающий литерал - это a в первом случае и a во втором. Необязательное разделение одинарных кавычек в или игнорируется при определении его значения. [ Плавающие литералы и имеют одинаковое значение. ] Можно опустить целую или дробную часть (но не обе сразу). В десятичном литерале с плавающей запятой можно опустить либо точку счисления, либо букву, либо и показатель степени (но не оба сразу). В шестнадцатеричном литерале с плавающей запятой можно опустить точку счисления (но не показатель степени). Целая часть, необязательная точка счисления и необязательная дробная часть образуют плавающий литерал. В десятичном литерале с плавающей запятой показатель степени, если он присутствует, указывает степень 10, с помощью которой следует масштабировать мантиссу. В шестнадцатеричном литерале с плавающей запятой показатель степени указывает степень двойки, на которую следует масштабировать мантиссу. [ Плавающие литералы и имеют одинаковое значение. ] Если масштабированное значение находится в диапазоне представляемых значений для своего типа, результатом является масштабированное значение, если оно представимо, иначе большее или меньшее представляемое значение, ближайшее к масштабируемому значению, выбранное способом, определяемым реализацией. Тип плавающего литерала не указан явно суффиксом. Суффиксы и укажите , суффиксы и укажите . Если масштабируемое значение не входит в диапазон представимых значений для его типа, программа имеет неправильный формат. e E p P 0x 0X decimal floating literal hexadecimal floating literal digit-sequencehexadecimal-digit-sequence Example: 1.602'176'565e-19 1.602176565e-19 — end example e E significand Example: 49.625 0xC.68p+2 — end example double f F float l L long double
string-literal: encoding-prefixopt " s-char-sequenceopt " encoding-prefixopt R raw-string
s-char-sequence: s-char s-char-sequence s-char
s-char: any member of the source character set except the double-quote ", backslash \, or new-line character escape-sequence universal-character-name
raw-string: " d-char-sequenceopt ( r-char-sequenceopt ) d-char-sequenceopt "
r-char-sequence: r-char r-char-sequence r-char
r-char: any member of the source character set, except a right parenthesis ) followed by the initial d-char-sequence (which may be empty) followed by a double quote ".
d-char-sequence: d-char d-char-sequence d-char
d-char: any member of the basic source character set except: space, the left parenthesis (, the right parenthesis ), the backslash \, and the control characters representing horizontal tab, vertical tab, form feed, and newline.
string-literalПредставляет собой последовательность символов (как определено в [lex.ccon]) в двойных кавычках, при необходимости с приставкой R, u8, u8R, u, uR, U, UR, L, или LR, как в "...", R"(...)", u8"...", u8R"**(...)**", u"...", uR"*~(...)*~", U"...", UR"zzz(...)zzz", L"...", или LR"(...)", соответственно.
string-literal, Что имеет в префиксе это . Символ служит разделителем. Окончание a - это та же последовательность символов, что и начальная . А должен состоять максимум из 16 знаков. R raw string literald-char-sequenced-char-sequenceraw-stringd-char-sequenced-char-sequence
[ Note: Символы '(' и ')' разрешены в raw-string. Таким образом, R"delimiter((a|b))delimiter" эквивалентно "(a|b)". ] — end note
[ Note: Новая строка исходного файла в необработанном строковом литерале приводит к новой строке в результирующем строковом литерале выполнения. Предполагая, что в начале строк в следующем примере нет пробелов, утверждение будет успешным:
const char* p = R"(a\ b c)"; assert(std::strcmp(p, "a\\\nb\nc") == 0);
— end note ]
[ Example: Необработанная строка
R"a( )\ a" )a"
эквивалентно "\n)\\\na\"\n". Необработанная строка
R"(??)"
эквивалентно "\?\?". Необработанная строка
R"#( )??=" )#"
эквивалентно "\n)\?\?=\"\n". ] — end example
После фазы трансляции 6 элемент a string-literal, который не начинается с символа encoding-prefixan ordinary string literal, инициализируется заданными символами.
Обычные строковые литералы и строковые литералы UTF-8 также называются узкими строковыми литералами. Узкий строковый литерал имеет тип «массив из n const char», где n - размер строки, как определено ниже, и имеет static storage duration.
Для строкового литерала UTF-8 каждый последующий элемент object representation имеет значение соответствующей кодовой единицы кодировки строки UTF-8.
A, string-literalкоторый начинается с u, например u"asdf", является char16_t строковым литералом. char16_t Строковый литерал имеет тип «массив n const char16_t», где n это размер строки , как определено ниже; он инициализируется заданными символами. Один c-charможет содержать более одного char16_t символа в виде суррогатных пар.
A, string-literalкоторый начинается с U, например U"asdf", является char32_t строковым литералом. char32_t Строковый литерал имеет тип «массив n const char32_t», где n это размер строки , как определено ниже; он инициализируется заданными символами.
string-literal, Который начинается с L, таких как L"asdf", является wide string literal. Широкий строковый литерал имеет тип «массив », где - размер строки, как определено ниже; он инициализируется заданными символами. n const wchar_t n
В translation phase 6, смежные string-literals объединяются. Если оба string-literals имеют одинаковые значения encoding-prefix, полученный конкатенированный строковый литерал будет иметь это encoding-prefix. Если у одного string-literalнет encoding-prefix, он рассматривается как один string-literalиз тех же, encoding-prefixчто и другой операнд. Если токен строкового литерала UTF-8 соседствует с токеном широкого строкового литерала, программа имеет неправильный формат. Любые другие конкатенации условно поддерживаются с поведением, определяемым реализацией. [ Note: Эта конкатенация является интерпретацией, а не преобразованием. Поскольку интерпретация происходит на этапе перевода 6 (после того, как каждый символ строкового литерала был переведен в значение из соответствующего набора символов), string-literalисходная грубость a не влияет на интерпретацию или правильность конкатенации. ] В таблице есть несколько примеров допустимых конкатенаций. — end note 9
Источник | Средства | Источник | Средства | Источник | Средства | |||
u"a" | u"b" | u"ab" | U"a" | U"b" | U"ab" | L"a" | L"b" | L"ab" |
u"a" | "b" | u"ab" | U"a" | "b" | U"ab" | L"a" | "b" | L"ab" |
"a" | u"b" | u"ab" | "a" | U"b" | U"ab" | "a" | L"b" | L"ab" |
Символы в составных строках сохраняются отдельно.
[ Example:
"\xA" "B"
содержит два символа '\xA' и 'B' после объединения (а не один шестнадцатеричный символ '\xAB'). ] — end example
После любой необходимой конкатенации к каждому строковому литералу добавляется in translation phase 7, '\0' чтобы программы, просматривающие строку, могли найти ее конец.
Escape-последовательности и universal-character-names в необработанных строковых литералах имеют то же значение, что и в character literals, за исключением того, что одинарная кавычка ' может быть представлена либо сама по себе, либо с помощью escape-последовательности \', а двойной кавычке " должен предшествовать a \, и за исключением того, что a universal-character-nameв char16_t строковом литерале может дать суррогатную пару. В узком строковом литерале a universal-character-nameможет отображаться более чем на один char элемент из-за multibyte encoding. Размер char32_t строкового литерала or - это общее количество управляющих последовательностей universal-character-names, и других символов, плюс один для завершающего U'\0' или L'\0'. Размер char16_t строкового литерала - это общее количество управляющих последовательностей, universal-character-namesи других символов, плюс один для каждого символа, требующего суррогатной пары, плюс один для завершения u'\0'. [ Note: Размер char16_t строкового литерала - это количество кодовых единиц, а не количество символов. ] В и строки литералов, любой должен быть в пределах до . Размер узкого строкового литерала - это общее количество escape-последовательностей и других символов, плюс по крайней мере один для многобайтовой кодировки каждого , плюс один для завершения . — end note char32_t char16_tuniversal-character-names 0x0 0x10FFFFuniversal-character-name '\0'
string-literalРезультатом оценки является объект строкового литерала со статической продолжительностью хранения, инициализированный заданными символами, как указано выше. Все ли строковые литералы различны (то есть хранятся в неперекрывающихся объектах) и не определено ли последовательные вычисления одного и string-literalтого же объекта или другого объекта. [ Эффект от попытки изменить строковый литерал не определен. ] Note: — end note
boolean-literal: false true
pointer-literal: nullptr
Литерал указателя - это ключевое слово nullptr. Это значение типа std::nullptr_t. [ Note: std::nullptr_t - это отдельный тип, который не является ни типом указателя, ни указателем на тип члена; скорее, prvalue этого типа является константой нулевого указателя и может быть преобразовано в значение нулевого указателя или значение указателя на нулевой член. Смотрите [conv.ptr] и [conv.mem]. ] — end note
user-defined-literal: user-defined-integer-literal user-defined-floating-literal user-defined-string-literal user-defined-character-literal
user-defined-integer-literal: decimal-literal ud-suffix octal-literal ud-suffix hexadecimal-literal ud-suffix binary-literal ud-suffix
user-defined-floating-literal: fractional-constant exponent-partopt ud-suffix digit-sequence exponent-part ud-suffix hexadecimal-prefix hexadecimal-fractional-constant binary-exponent-part ud-suffix hexadecimal-prefix hexadecimal-digit-sequence binary-exponent-part ud-suffix
user-defined-string-literal: string-literal ud-suffix
user-defined-character-literal: character-literal ud-suffix
ud-suffix: identifier
Если токен соответствует обоим user-defined-literalи другому literalтипу, он считается последним. [ Example: 123_km - это user-defined-literal, но 12LL это - integer-literal. ] Синтаксический нетерминал, предшествующий в a, считается самой длинной последовательностью символов, которая может соответствовать этому нетерминальному. — end example ud-suffixuser-defined-literal
A user-defined-literalрассматривается как вызов literal operator или literal operator template. Чтобы определить форму этого вызова для заданного user-defined-literal L с ud-suffix X, literal-operator-idищется буквальный идентификатор суффикса X в контексте L использования правил для unqualified name lookup. Позвольте S быть набором объявлений, найденных этим поиском. S не должно быть пустым.
Если L это a user-defined-integer-literal, пусть n будет буквальным без его ud-suffix. Если S содержит буквальный оператор с типом параметра unsigned long long, литерал L обрабатывается как вызов формы
operator "" X(nULL)
В противном случае S должен содержать a raw literal operator или a, literal operator template но не оба сразу. Если S содержит необработанный буквальный оператор, литерал L рассматривается как вызов формы
operator "" X("n")
В противном случае (S содержит шаблон буквального оператора) L рассматривается как вызов формы
operator "" X<'c1', 'c2', ... 'ck'>()
где n - исходная последовательность символов c1c2...ck. [ Note: Последовательность c1c2...ck может содержать только символы из базового исходного набора символов. ] — end note
Если L это a user-defined-floating-literal, пусть f будет буквальным без его ud-suffix. Если S содержит буквальный оператор с типом параметра long double, литерал L обрабатывается как вызов формы
operator "" X(fL)
В противном случае S должен содержать a raw literal operator или a, literal operator template но не оба сразу. Если S содержит необработанный буквальный оператор, literal L рассматривается как вызов формы
operator "" X("f")
В противном случае (S содержит шаблон буквального оператора) L рассматривается как вызов формы
operator "" X<'c1', 'c2', ... 'ck'>()
где f - исходная последовательность символов c1c2...ck. [ Note: Последовательность c1c2...ck может содержать только символы из базового исходного набора символов. ] — end note
Если L - a user-defined-string-literal, пусть str будет литералом без его, ud-suffixа пусть len будет числом кодовых единиц в str (т. Е. Его длиной, исключая завершающий нулевой символ). Литерал L рассматривается как вызов формы
operator "" X(str, len)
Если L это a user-defined-character-literal, пусть ch будет буквальным без его ud-suffix. S должен содержать literal operator , единственный параметр которого имеет тип, ch а литерал L обрабатывается как вызов формы
operator "" X(ch)
[ Example:
long double operator "" _w(long double); std::string operator "" _w(const char16_t*, std::size_t); unsigned operator "" _w(const char*); int main() { 1.2_w; // calls operator "" _w(1.2L) u"one"_w; // calls operator "" _w(u"one", 3) 12_w; // calls operator "" _w("12") "two"_w; // error: no applicable literal operator }
— end example ]
В translation phase 6смежные строковые литералы объединяются и user-defined-string-literals для этой цели считаются строковыми литералами. Во время конкатенации ud-suffixes удаляются и игнорируются, и происходит процесс конкатенации, как описано в [lex.string]. В конце фазы 6, если строковый литерал является результатом конкатенации, включающей хотя бы один user-defined-string-literal, все участвующие user-defined-string-literals должны иметь то же самое, ud-suffix и этот суффикс применяется к результату конкатенации.