Namespaces
Variants

Character literal

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

Содержание

Синтаксис

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

Объяснение

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 не может быть закодирован как единичная кодовая единица в 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 символьном литерале, не может быть представлено соответствующим типом char N _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 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 для Символьная константа