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,
  • управляющая последовательность, определённая в разделе управляющие последовательности
  • универсальное имя символа, определённое в разделе управляющие последовательности
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 не является числовой управляющей последовательностью (см. ниже), а также не представим в кодировке символов, связанной с литералом, или не может быть закодирован одной кодовой единицей в этой кодировке (например, значение вне базовой многоязычной плоскости в Windows, где wchar_t имеет разрядность 16 бит), программа некорректна.
6) Если какой-либо символ c-char в c-char-sequence не может быть закодирован одной кодовой единицей в кодировке обычных литералов, программа некорректна.
7) Если какой-либо символ c-char в c-char-sequence не может быть закодирован одной кодовой единицей в кодировке широких литералов, программа некорректна. (до C++23)

Числовые управляющие последовательности

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

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

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

(начиная с C++23)

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

(до C++23)

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

(начиная с C++23)

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

(начиная с 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

Spec-Zone.ru

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