Character literal
Содержание |
Синтаксис
'
c-char
'
|
(1) | ||||||||
u8'
c-char
'
|
(2) | (начиная с C++17) | |||||||
u'
c-char
'
|
(3) | (начиная с C++11) | |||||||
U'
c-char
'
|
(4) | (начиная с C++11) | |||||||
L'
c-char
'
|
(5) | ||||||||
'
c-char-sequence
'
|
(6) | ||||||||
L'
c-char-sequence
'
|
(7) | (до C++23) | |||||||
| c-char | - |
либо
|
| basic-c-char | - | Символ из basic source character set (until C++23) translation character set (since C++23) , за исключением одинарной кавычки ' , обратной косой черты \ или символа новой строки |
| c-char-sequence | - | два или более c-char s |
Объяснение
Некодируемые символы
|
7)
Если любой
c-char
в
c-char-sequence
не может быть закодирован как единичная кодовая единица в
wide literal encoding
, программа является некорректной.
|
(until C++23) |
Числовые escape-последовательности
Числовые (восьмеричные и шестнадцатеричные) escape-последовательности могут использоваться для указания значения символа.
|
Если символьный литерал содержит только одну числовую escape-последовательность, и значение, заданное escape-последовательностью, представимо беззнаковой версией его типа, то символьный литерал имеет то же значение, что и указанное значение (возможно, после преобразования в символьный тип). UTF- N символьный литерал может иметь любое значение, представимое его типом. Если значение не соответствует валидной кодовой точке Unicode, или если соответствующая кодовая точка не может быть представлена как единая кодовая единица в UTF- N , оно всё равно может быть задано числовой escape-последовательностью с этим значением. Например, u8 ' \xff ' является корректным и эквивалентно char8_t ( 0xFF ) . |
(since C++23) |
|
Если значение, заданное числовой escape-последовательностью, используемой в обычном или широком символьном литерале, не представимо в char или wchar_t соответственно, то значение символьного литерала определяется реализацией. |
(до C++23) |
|
Если значение, заданное числовой escape-последовательностью, используемой в обычном или широком символьном литерале с одним c-char , представимо беззнаковой версией базового типа char или wchar_t соответственно, то значение литерала является целочисленным значением этого беззнакового целочисленного типа и заданным значением, преобразованным к типу литерала. В противном случае программа является некорректной. |
(начиная с C++23) |
|
Если значение, заданное числовой escape-последовательностью, используемой в UTF-
N
символьном литерале, не может быть представлено соответствующим типом
|
(начиная с C++11) |
Примечания
Многобайтовые литералы были унаследованы языком C из языка программирования B. Хотя стандартами C или C++ это не определено, большинство компиляторов (заметным исключением является MSVC) реализуют многобайтовые литералы в соответствии со спецификацией B: значения каждого символа в литерале инициализируют последовательные байты результирующего целого числа в порядке big-endian с выравниванием по правому краю и дополнением нулями, например, значение ' \1 ' равно 0x00000001 , а значение ' \1 \2 \3 \4 ' равно 0x01020304 .
В языке C символьные константы, такие как 'a' или ' \n ' имеют тип int , а не char .
Пример
#include <cstdint> #include <iomanip> #include <iostream> #include <string_view> template<typename CharT> void dump(std::string_view s, const CharT c) { const uint8_t* data{reinterpret_cast<const uint8_t*>(&c)}; std::cout << s << " \t" << std::hex << std::uppercase << std::setfill('0'); for (auto i{0U}; i != sizeof(CharT); ++i) std::cout << std::setw(2) << static_cast<unsigned>(data[i]) << ' '; std::cout << '\n'; } void print(std::string_view str = "") { std::cout << str << '\n'; } int main() { print("Ordinary character literals:"); char c1 = 'a'; dump("'a'", c1); char c2 = '\x2a'; dump("'*'", c2); print("\n" "Ordinary multi-character literals:"); int mc1 = 'ab'; dump("'ab'", mc1); // implementation-defined int mc2 = 'abc'; dump("'abc'", mc2); // implementation-defined print("\n" "UTF-8 character literals:"); char8_t C1 = u8'a'; dump("u8'a'", C1); // char8_t C2 = u8'¢'; dump("u8'¢'", C2); // error: ¢ maps to two UTF-8 code units // char8_t C3 = u8'猫'; dump("u8'猫'", C3); // error: 猫 maps to three UTF-8 code units // char8_t C4 = u8'🍌'; dump("u8'🍌'", C4); // error: 🍌 maps to four UTF-8 code units print("\n" "UTF-16 character literals:"); char16_t uc1 = u'a'; dump("u'a'", uc1); char16_t uc2 = u'¢'; dump("u'¢'", uc2); char16_t uc3 = u'猫'; dump("u'猫'", uc3); // char16_t uc4 = u'🍌'; dump("u'🍌'", uc4); // error: 🍌 maps to two UTF-16 code units print("\n" "UTF-32 character literals:"); char32_t Uc1 = U'a'; dump("U'a'", Uc1); char32_t Uc2 = U'¢'; dump("U'¢'", Uc2); char32_t Uc3 = U'猫'; dump("U'猫'", Uc3); char32_t Uc4 = U'🍌'; dump("U'🍌'", Uc4); print("\n" "Wide character literals:"); wchar_t wc1 = L'a'; dump("L'a'", wc1); wchar_t wc2 = L'¢'; dump("L'¢'", wc2); wchar_t wc3 = L'猫'; dump("L'猫'", wc3); wchar_t wc4 = L'🍌'; dump("L'🍌'", wc4); // unsupported on Windows since C++23 }
Возможный вывод:
Ordinary character literals: 'a' 61 '*' 2A Ordinary multi-character literals: 'ab' 62 61 00 00 'abc' 63 62 61 00 UTF-8 character literals: u8'a' 61 UTF-16 character literals: u'a' 61 00 u'¢' A2 00 u'猫' 2B 73 UTF-32 character literals: U'a' 61 00 00 00 U'¢' A2 00 00 00 U'猫' 2B 73 00 00 U'🍌' 4C F3 01 00 Wide character literals: L'a' 61 00 00 00 L'¢' A2 00 00 00 L'猫' 2B 73 00 00 L'🍌' 4C F3 01 00
Отчеты о дефектах
Следующие отчеты об изменениях поведения, влияющие на дефекты, были применены задним числом к ранее опубликованным стандартам C++.
| DR | Applied to | Behavior as published | Correct behavior |
|---|---|---|---|
| CWG 912 | C++98 | non-encodable ordinary character literal was unspecified | specified as conditionally-supported |
| CWG 1024 | C++98 | multicharacter literal was required to be supported | made conditionally-supported |
| CWG 1656 | C++98 |
the meaning of numeric escape sequence
in a character literal was unclear |
specified |
| P1854R4 | C++98 | non-encodable character literals were conditionally-supported | the program is ill-formed |
Ссылки
- Стандарт C++23 (ISO/IEC 14882:2024):
-
- 5.13.3 Символьные литералы [lex.ccon]
- Стандарт C++20 (ISO/IEC 14882:2020):
-
- 5.13.3 Символьные литералы [lex.ccon]
- Стандарт C++17 (ISO/IEC 14882:2017):
-
- 5.13.3 Символьные литералы [lex.ccon]
- Стандарт C++14 (ISO/IEC 14882:2014):
-
- 2.14.3 Символьные литералы [lex.ccon]
- Стандарт C++11 (ISO/IEC 14882:2011):
-
- 2.14.3 Символьные литералы [lex.ccon]
- Стандарт C++03 (ISO/IEC 14882:2003):
-
- 2.13.2 Символьные литералы [lex.ccon]
- Стандарт C++98 (ISO/IEC 14882:1998):
-
- 2.13.2 Символьные литералы [lex.ccon]
Смотрите также
| пользовательские литералы (C++11) | литералы с пользовательским суффиксом |
|
документация C
для
Символьная константа
|
|