Spec-Zone.ru › C++

Литерал символа

Синтаксис

'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,
  • последовательность escape, как определено в последовательностях escape
  • универсальное имя символа, как определено в последовательностях escape
basic-c-char - Символ из основного набора символов исходного текста(до C++23)набора символов перевода(с C++23), за исключением одиночной кавычки ', обратного слеша \, или символа новой строки
c-char-sequence - две или более c-char

Объяснение

1) Обычный литерал символа, например, 'a' или '\n' или '\13'. Такой литерал имеет тип char и значение, равное представлению c-char в наборе символов выполнения(до C++23)соответствующему кодовому пункту из кодирования обычных литералов(с C++23).
2) UTF-8 литерал символа, например, u8'a'. Такой литерал имеет тип char(до C++20)char8_t(с C++20) и значение, равное значению кодового пункта ISO/IEC 10646 для c-char, при условии, что значение кодового пункта представимо одним кодовым блоком UTF-8 (т. е., c-char находится в диапазоне 0x0-0x7F включительно).
3) UTF-16 литерал символа, например, u'猫', но не u'🍌' (u'\U0001f34c'). Такой литерал имеет тип char16_t и значение, равное значению кодового пункта ISO/IEC 10646 для c-char, при условии, что значение кодового пункта представимо одним кодовым блоком UTF-16 (т. е., c-char находится в диапазоне 0x0-0xFFFF включительно).
4) UTF-32 литерал символа, например, U'猫' или U'🍌'. Такой литерал имеет тип char32_t и значение, равное значению кодового пункта ISO/IEC 10646 для c-char.
5) Литерал широкого символа, например, L'β' или L'猫'. Такой литерал имеет тип wchar_t и значение, равное значению c-char в наборе символов выполнения(до C++23)соответствующему кодовому пункту из кодирования широких литералов(с C++23).
6) Обычный литерал многосимвольного символа(до C++23)Многосимвольный литерал(с C++23), например, 'AB', поддерживается условно, имеет тип int и значение, определяемое реализацией.
7) Литерал широкого многосимвольного символа, например, L'AB', поддерживается условно, имеет тип wchar_t и значение, определяемое реализацией.

Некодируемые символы

1-5) Если c-char не является числовой последовательностью escape (см. ниже), если c-char не представим в кодировке литерала или не может быть закодирован как единичный код в этой кодировке (например, не-BMP значение в Windows, где wchar_t 16-битное), программа является ошибочной.
6) Если какой-либо c-char в c-char-sequence не может быть закодирован как единичный код в кодировке обычных литералов, программа является ошибочной.
7) Если какой-либо c-char в c-char-sequence не может быть закодирован как единичный код в кодировке широких литералов, программа является ошибочной. (до C++23)

Числовые последовательности escape

Числовые (восьмеричные и шестнадцатеричные) последовательности escape могут использоваться для указания значения символа.

Если литерал символа содержит только одну числовую последовательность escape, и значение, указанное последовательностью escape, представимо беззнаковой версией своего типа, литерал символа имеет то же значение, что и указанное значение (возможно, после преобразования в тип символа).

Литерал символа UTF-N может иметь любое значение, представимое его типом. Если значение не соответствует допустимому кодовому пункту Unicode, или если соответствующий кодовый пункт не представим как единичный код в UTF-N, его всё равно можно указать с помощью числовой последовательности escape со значением. Например, u8'\xff' корректно сформирован и равен char8_t(0xFF).

(с C++23)

Если значение, указанное числовой последовательностью escape, используемой в обычном или широком литерале символа, не представимо соответственно для char или wchar_t, значение литерала символа определено реализацией.

(до C++23)

Если значение, заданное числовой последовательностью escape, используемой в обычном или широком литерале символа с одним c-char, представимо беззнаковой версией базового типа char или wchar_t соответственно, значение литерала — целочисленное значение этого беззнакового целочисленного типа и указанное значение, преобразованное к типу литерала. В противном случае программа является ошибочной.

(с C++23)

Если значение, указанное числовой последовательностью escape, используемой в UTF-N литерале символа, не представимо соответствующим charN_t, значение литерала символа определено реализацией(до C++17)программа является ошибочной(с C++17).

(с 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 Применимо к Поведение, опубликованное в спецификации Правильное поведение
CWG 912 C++98 некодируемый обычный символьный литерал был неопределён определён как условно поддерживаемый
CWG 1024 C++98 многосимвольный литерал должен был поддерживаться сделано условно поддерживаемым
CWG 1656 C++98 значение числовой последовательности escape
в символьном литерале было неясно
определено
P1854R4 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 для Символьная константа

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/language/character_literal

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API