Символьный литерал
Синтаксис
'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 | - | Символ из базового исходного набора символов(до C++23)набора символов трансляции(начиная с C++23), кроме одинарной кавычки ', обратной косой черты \ или символа новой строки |
| c-char-sequence | - | два или более символа c-char |
Пояснение
'a' или '\n' или '\13'. Такой литерал имеет тип char и значение, равное представлению c-char в наборе символов выполнения(до C++23)соответствующей кодовой точке из кодировки обычных литералов(начиная с C++23).u8'a'. Такой литерал имеет тип char(до C++20)char8_t(начиная с C++20) и значение, равное значению кодовой точки ISO/IEC 10646 для c-char, при условии, что значение кодовой точки представимо одной кодовой единицей UTF-8 (то есть c-char находится в диапазоне 0x0–0x7F включительно).u'猫', но не u'🍌' (u'\U0001f34c'). Такой литерал имеет тип char16_t и значение, равное значению кодовой точки ISO/IEC 10646 для c-char, при условии, что значение кодовой точки представимо одной кодовой единицей UTF-16 (то есть c-char находится в диапазоне 0x0–0xFFFF включительно).U'猫' или U'🍌'. Такой литерал имеет тип char32_t и значение, равное значению кодовой точки ISO/IEC 10646 для c-char.L'β' или L'猫'. Такой литерал имеет тип wchar_t и значение, равное значению c-char в наборе широких символов выполнения(до C++23)соответствующей кодовой точке из кодировки широких литералов(начиная с C++23).'AB', поддерживается условно, имеет тип int и значение, определяемое реализацией.L'AB', поддерживается условно, имеет тип wchar_t и значение, определяемое реализацией.Непредставимые символы
| 7) Если какой-либо символ c-char в c-char-sequence не может быть закодирован одной кодовой единицей в кодировке широких литералов, программа некорректна. | (до C++23) |
Числовые управляющие последовательности
Числовые (восьмеричные и шестнадцатеричные) управляющие последовательности можно использовать для задания значения символа.
| Если символьный литерал содержит только одну числовую управляющую последовательность и заданное ею значение представимо беззнаковым вариантом его типа, символьный литерал имеет то же значение, что и заданное значение (возможно, после преобразования к символьному типу). Символьный литерал UTF-N может иметь любое значение, представимое его типом. Если это значение не соответствует допустимой кодовой точке Unicode или соответствующая ему кодовая точка не представима одной кодовой единицей UTF-N, его всё равно можно задать числовой управляющей последовательностью с этим значением. Например, | (начиная с C++23) |
| Если значение, заданное числовой управляющей последовательностью, используемой в обычном или широком символьном литерале, не представимо соответственно типом char или wchar_t, значение символьного литерала определяется реализацией. | (до C++23) |
| Если значение, заданное числовой управляющей последовательностью, используемой в обычном или широком символьном литерале с одним символом c-char, представимо беззнаковым вариантом базового типа соответственно char или wchar_t, значение литерала равно целочисленному значению этого беззнакового целочисленного типа и заданному значению, преобразованному к типу литерала. В противном случае программа некорректна. | (начиная с 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("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 | Применён к | Поведение согласно опубликованной версии | Исправленное поведение |
|---|---|---|---|
| CWG 912 | C++98 | непредставимый обычный символьный литерал имел неопределённый статус | указано, что он поддерживается условно |
| CWG 1024 | C++98 | поддержка многосимвольного литерала была обязательной | поддержка стала условной |
| CWG 1656 | C++98 | значение числовой управляющей последовательности в символьном литерале было неясным | определено |
| P1854R4 | C++98 | непредставимые символьные литералы поддерживались условно | программа некорректна |
Ссылки
- Стандарт 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 о символьной константе | |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/language/character_literal