Символьный литерал
Синтаксис
'c-символ '
|
(1) | ||||||||
u8'c-символ '
|
(2) | (начиная с C++17) | |||||||
u'c-символ '
|
(3) | (начиная с C++11) | |||||||
U'c-символ '
|
(4) | (начиная с C++11) | |||||||
L'c-символ '
|
(5) | ||||||||
'последовательность-c-символов '
|
(6) | ||||||||
L'последовательность-c-символов '
|
(7) | ||||||||
| c-символ | — | одно из
|
| базовый-c-символ | — | Символ из исходного набора символов (до C++23)набора символов трансляции (начиная с C++23), за исключением одиночной кавычки ', обратной косой черты \ или символа новой строки
|
| последовательность-c-символов | — | два или более c-символа |
Объяснение
'a' или '\n' или '\13'. Такой литерал имеет тип char и значение, равное представлению c-символа в в наборе символов выполнения (до C++23)соответствующей кодовой точке из обычной литеральной кодировки (начиная с C++23).u8'a'. Такой литерал имеет тип char (до C++20)char8_t (начиная с C++20) и значение, равное значению кодовой точки ISO 10646 c-символа, при условии, что значение кодовой точки может быть представлено с помощью одной кодовой единицы UTF-8 (то есть, c-символ находится в диапазоне 0x0-0x7F включительно).u'猫', но не u'🍌' (u'\U0001f34c'). Такой литерал имеет тип char16_t и значение, равное значению кодовой точки ISO 10646 c-символа, при условии, что значение кодовой точки может быть представлено одной кодовой единицей UTF-16 (что есть c-символ в диапазоне 0x0-0xFFFF, включительно).U'猫' или U'🍌'. Такой литерал имеет тип char32_t и значение, равное значению кодовой точки ISO 10646 c-символа.L'β' или L'猫'. Такой литерал имеет тип wchar_t и значение, равное значению c-символа в наборе широких символов выполнения (до C++23)соответствующей кодовой точки из широкой литеральной кодировки (начиная с C++23).'AB', поддерживается условно, имеет тип int и значение, определяемое реализацией.L'AB', поддерживается условно, имеет тип wchar_t и значение, определяемое реализацией.Некодируемые символы
wchar_t 16-битное), программа некорректна.|
7) Если какой-либо c-символ в последовательности-c-символов не может быть закодирован как одна кодовая единица в широком литеральном кодировании, программа некорректна.
|
(до C++23) |
Числовые управляющие последовательности
Числовые (восьмеричные и шестнадцатеричные) управляющие последовательности могут использоваться для указания значения символа.
|
Если символьный литерал содержит только одну числовую управляющую последовательность, а значение, заданное управляющей последовательностью, может быть представлено беззнаковой версией его типа, символьный литерал имеет то же значение, что и указанное значение (возможно, после преобразования в символьный тип). Символьный литерал UTF-N может иметь любое значение, представляемое его типом. Если значение не соответствует действительной кодовой точке Юникода или если соответствующая ей кодовая точка не может быть представлена как одиночная кодовая единица в UTF-N, её все равно можно указать числовой управляющей последовательностью со значением. Например |
(начиная с C++23) |
|
Если значение, заданное числовой управляющей последовательностью, используемой в литерале обычного или расширенного символа, не может быть представлено с помощью |
(до C++23) |
|
Если значение, заданное числовой управляющей последовательностью, используемой в литерале обычного или расширенного символа с одним c-символом, может быть представлено беззнаковой версией базового типа |
(начиная с C++23) |
|
Если значение, заданное числовой управляющей последовательностью, используемой в символьном литерале UTF-N, не может быть представлено соответствующим |
(начиная с C++11) |
Примечание
Многосимвольные литералы были унаследованы C от языка программирования B. Хотя это и не указано в стандарте C или C++, большинство компиляторов (за исключением MSVC) реализуют многосимвольные литералы, как указано в B: значения каждого символа в литерале инициализируют последовательные байты результирующего целого числа от старшего к младшему, дополненного нулями, скорректированному вправо порядке, например, значение '\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("Литералы обычных символов:");
char c1 = 'a'; dump("'a'", c1);
char c2 = '\x2a'; dump("'*'", c2);
print("\n" "Обычные многосимвольные литералы:");
int mc1 = 'ab'; dump("'ab'", mc1); // определено реализацией
int mc2 = 'abc'; dump("'abc'", mc2); // определено реализацией
print("\n" "Символьные литералы UTF-8:");
char8_t C1 = u8'a'; dump("u8'a'", C1);
// char8_t C2 = u8'¢'; dump("u8'¢'", C2); // ошибка: ¢ сопоставляется с двумя
// кодовыми единицами UTF-8
// char8_t C3 = u8'猫'; dump("u8'猫'", C3); // ошибка: 猫 сопоставляется с тремя
// кодовыми единицами UTF-8
// char8_t C4 = u8'🍌'; dump("u8'🍌'", C4); // ошибка: 🍌 сопоставляется с четырьмя
// кодовыми единицами UTF-8
print("\n" "Символьные литералы UTF-16:");
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); // ошибка: 🍌 сопоставляется с двумя
// кодовыми единицами UTF-16
print("\n" "Символьные литералы UTF-32:");
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" "Литералы широких символов:");
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);
}
Возможный вывод:
Литералы обычных символов:
'a' 61
'*' 2A
Обычные многосимвольные литералы:
'ab' 62 61 00 00
'abc' 63 62 61 00
Символьные литералы UTF-8:
u8'a' 61
Символьные литералы UTF-16:
u'a' 61 00
u'¢' A2 00
u'猫' 2B 73
Символьные литералы UTF-32:
U'a' 61 00 00 00
U'¢' A2 00 00 00
U'猫' 2B 73 00 00
U'🍌' 4C F3 01 00
Литералы широких символов:
L'a' 61 00 00 00
L'¢' A2 00 00 00
L'猫' 2B 73 00 00
L'🍌' 4C F3 01 00
Отчёты о дефектах
Следующие изменения поведения были применены с обратной силой к ранее опубликованным стандартам C++:
| Номер | Применён | Поведение в стандарте | Корректное поведение |
|---|---|---|---|
| CWG 912 | C++98 | некодируемый литерал обычного символа не был специфицирован |
специфицирован как условно-поддерживаемый |
| CWG 1024 | C++98 | многосимвольный литерал должен был поддерживаться | сделан условно-поддерживаемым |
| CWG 1656 | C++98 | значение числовой управляющей последовательности в символьном литерале неясно |
специфицировано |
| WG не указан | C++98 | некодируемые символьные литералы поддерживались условно |
программа некорректна |
Ссылки
- C++23 стандарт (ISO/IEC 14882:2023):
- 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 по Символьная константа
| |