Namespaces
Variants

String 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

Содержание

Синтаксис

" s-char-seq  (необязательно) " (1)
R" d-char-seq  (необязательно) ( r-char-seq  (необязательно) ) d-char-seq  (необязательно) " (2) (начиная с C++11)
L" s-char-seq  (необязательно) " (3)
LR" d-char-seq  (необязательно) ( r-char-seq  (необязательно) ) d-char-seq  (необязательно) " (4) (начиная с C++11)
u8" s-char-seq  (необязательно) " (5) (начиная с C++11)
u8R" d-char-seq  (необязательно) ( r-char-seq  (необязательно) ) d-char-seq  (необязательно) " (6) (начиная с C++11)
u" s-char-seq  (необязательно) " (7) (начиная с C++11)
uR" d-char-seq  (необязательно) ( r-char-seq  (необязательно) ) d-char-seq  (необязательно) " (8) (начиная с C++11)
U" s-char-seq  (необязательно) " (9) (начиная с C++11)
UR" d-char-seq  (необязательно) ( r-char-seq  (необязательно) ) d-char-seq  (необязательно) " (10) (начиная с C++11)

Объяснение

s-char-seq - Последовательность из одного или более s-char ов
s-char - Один из
  • basic-s-char
  • escape-последовательность, как определено в escape sequences
  • универсальное имя символа, как определено в escape sequences
basic-s-char - Символ из basic source character set (until C++23) translation character set (since C++23) , за исключением двойной кавычки " , обратной косой черты \ или символа новой строки
d-char-seq - Последовательность из одного или более d-char ов, длиной не более 16 символов
d-char - Символ из basic source character set (until C++23) basic character set (since C++23) , за исключением круглых скобок, обратной косой черты и пробелов
r-char-seq - Последовательность из одного или более r-char ов, за исключением того, что она не должна содержать закрывающую последовательность ) d-char-seq "
r-char - Символ из basic source character set (until C++23) translation character set (since C++23)

Синтаксис Вид Тип Кодировка
(1,2) обычный строковый литерал const char [ N ] обычная кодировка литералов
(3,4) широкий строковый литерал const wchar_t [ N ] широкая кодировка литералов
(5,6) UTF-8 строковый литерал

const char [ N ]

(до C++20)

const char8_t [ N ]

(начиная с C++20)
UTF-8
(7,8) UTF-16 строковый литерал const char16_t [ N ] UTF-16
(9,10) UTF-32 строковый литерал const char32_t [ N ] UTF-32

В перечисленных в таблице выше типах, N представляет количество закодированных единиц кода, которое определяется ниже .

Обычные и UTF-8 (since C++11) строковые литералы вместе называются узкими строковыми литералами.

Вычисление строкового литерала приводит к созданию объекта строкового литерала со статической продолжительностью хранения . Хранятся ли все строковые литералы в неперекрывающихся объектах и приводят ли последовательные вычисления строкового литерала к одному и тому же или разным объектам - не определено.

Эффект от попытки модификации строкового литерального объекта не определён.

bool b = "bar" == 3 + "foobar"; // может быть true или false, не определено
const char* pc = "Hello";
char* p = const_cast<char*>(pc);
p[0] = 'M'; // неопределенное поведение

Сырые строковые литералы

Сырые строковые литералы — это строковые литералы с префиксом, содержащим R (синтаксисы (2,4,6,8,10) ). Они не экранируют никакие символы, что означает, что всё между разделителями d-char-seq  ( и ) d-char-seq становится частью строки. Завершающая d-char-seq представляет собой ту же последовательность символов, что и начальная d-char-seq .

// OK: contains one backslash,
// equivalent to "\\"
R"(\)";
// OK: contains four \n pairs,
// equivalent to "\\n\\n\\n\\n"
R"(\n\n\n\n)";
// OK: contains one close-parenthesis, two double-quotes and one open-parenthesis,
// equivalent to ")\"\"("
R"-()""()-";
// OK: equivalent to "\n)\\\na\"\"\n"
R"a(
)\
a""
)a";
// OK: equivalent to "x = \"\"\\y\"\""
R"(x = ""\y"")";
// R"<<(-_-)>>"; // Error: begin and end delimiters do not match
// R"-()-"-()-"; // Error: )-" appears in the middle and terminates the literal
(начиная с C++11)

Инициализация

Объекты строковых литералов инициализируются последовательностью значений кодовых единиц, соответствующих последовательности s-char ов и r-char ов (начиная с C++11) , плюс завершающий нулевой символ (U+0000), в следующем порядке:

1) Для каждой непрерывной последовательности basic-s-char ов, r-char ов, (since C++11) simple escape sequences и universal character names , последовательность символов, которую она обозначает, кодируется в последовательность кодовых единиц с использованием связанной кодировки символов строкового литерала. Если символ не имеет представления в связанной кодировке символов, программа является некорректной.
Если связанная кодировка символов является состоятельной, первая такая последовательность кодируется, начиная с начального состояния кодировки, а каждая последующая последовательность кодируется, начиная с конечного состояния кодировки предыдущей последовательности.
2) Для каждой числовой escape-последовательности , принимая v как целочисленное значение, представленное восьмеричным или шестнадцатеричным числом, состоящим из последовательности цифр в escape-последовательности, и T как тип элемента массива строкового литерала (см. таблицу выше ):
  • Если v не превышает диапазон представимых значений типа T , то escape-последовательность добавляет одну кодовую единицу со значением v .
  • Иначе, если строковый литерал имеет синтаксис (1) или (3) , и (начиная с C++11) v не превышает диапазон представимых значений соответствующего беззнакового типа для базового типа T , то escape-последовательность добавляет одну кодовую единицу с уникальным значением типа T , которое сравнимо с v mod 2 S
    , где S — это ширина T .
  • Иначе программа является некорректной.
Если связанная кодировка символов является состоятельной, все такие последовательности не влияют на состояние кодировки.
3) Каждый условный escape-последовательность вносит определяемую реализацией последовательность кодовых единиц.
Если связанная кодировка символов является состоятельной, то влияние этих последовательностей на состояние кодировки определяется реализацией.

Конкатенация

Смежные строковые литералы объединяются на фазе трансляции 6 (после препроцессинга):

  • Если два строковых литерала одного типа , то объединённый строковый литерал также будет этого типа.
  • Если обычный строковый литерал расположен рядом с широким строковым литералом, поведение не определено.
(until C++11)
  • Если обычный строковый литерал расположен рядом с необычным строковым литералом, результирующий строковый литерал имеет тип последнего.
  • Если UTF-8 строковый литерал расположен рядом с широким строковым литералом, программа некорректна.
  • Любая другая комбинация условно поддерживается с семантикой, определяемой реализацией. [1]
(until C++23)
  • Любая другая комбинация некорректна.
(since C++23)
(since C++11)
"Hello, " "world!" // на фазе 6, 2 строковых литерала образуют "Hello, world!"
L"Δx = %" PRId16   // на фазе 4, PRId16 раскрывается в "d"
                   // на фазе 6, L"Δx = %" и "d" образуют L"Δx = %d"
  1. Ни одна известная реализация не поддерживает такую конкатенацию.

Невычисляемые строки

Следующие контексты ожидают строковый литерал, но не вычисляют его:

(начиная с C++11)
(начиная с C++14)
(начиная с C++20)
(начиная с C++26)


Не указано, разрешены ли необычные строковые литералы в этих контекстах , за исключением того, что имя литерального оператора должно использовать обычный строковый литерал (since C++11) .

(until C++26)

Только обычные строковые литералы разрешены в этих контекстах.

Каждое универсальное имя символа и каждая простая escape-последовательность в невычисляемой строке заменяется членом набора символов трансляции , который она обозначает. Невычисляемая строка, содержащая числовую escape-последовательность или условную escape-последовательность, является некорректной.

(since C++26)

Примечания

Строковые литералы могут использоваться для инициализации символьных массивов . Если массив инициализируется как char str [ ] = "foo" ; , str будет содержать копию строки "foo" .

Строковые литералы конвертируемы и присваиваемы к не-const char * или wchar_t * для совместимости с C, где строковые литералы имеют типы char [ N ] и wchar_t [ N ] . Такая неявная конвертация устарела.

(until C++11)

Строковые литералы не конвертируемы и не присваиваемы к не-const CharT* . Для такой конвертации необходимо использовать явное приведение (например, const_cast ).

(since C++11)

Строковый литерал не обязательно является нуль-терминированной последовательностью символов: если строковый литерал содержит встроенные нулевые символы, он представляет массив, содержащий более одной строки.

const char* p = "abc\0def"; // std::strlen(p) == 3, но массив имеет размер 8

Если допустимая шестнадцатеричная цифра следует за шестнадцатеричной escape-последовательностью в строковом литерале, это приведет к ошибке компиляции как недопустимая escape-последовательность. В качестве обходного решения можно использовать конкатенацию строк:

//const char* p = "\xfff"; // ошибка: шестнадцатеричная escape-последовательность вне диапазона
const char* p = "\xff""f"; // OK: литерал имеет тип const char[3] содержащий {'\xff','f','\0'}
Макрос тестирования возможностей Значение Стандарт Возможность
__cpp_char8_t 202207L (C++23)
(DR20)
char8_t исправление совместимости и переносимости (разрешает инициализацию ( unsigned ) char массивов из строковых литералов UTF-8)
__cpp_raw_strings 200710L (C++11) Сырые строковые литералы
__cpp_unicode_literals 200710L (C++11) Юникодные строковые литералы

Пример

#include <iostream>
// array1 и array2 содержат одинаковые значения:
char array1[] = "Foo" "bar";
char array2[] = {'F', 'o', 'o', 'b', 'a', 'r', '\0'};
const char* s1 = R"foo(
Hello
  World
)foo";
// то же самое, что
const char* s2 = "\nHello\n  World\n";
// то же самое, что
const char* s3 = "\n"
                 "Hello\n"
                 "  World\n";
const wchar_t* s4 = L"ABC" L"DEF"; // OK, то же самое, что
const wchar_t* s5 = L"ABCDEF";
const char32_t* s6 = U"GHI" "JKL"; // OK, то же самое, что
const char32_t* s7 = U"GHIJKL";
const char16_t* s9 = "MN" u"OP" "QR"; // OK, то же самое, что
const char16_t* sA = u"MNOPQR";
// const auto* sB = u"Mixed" U"Types";
        // до C++23 может поддерживаться или не поддерживаться
        // реализацией; некорректно начиная с C++23
const wchar_t* sC = LR"--(STUV)--"; // OK, сырой строковый литерал
int main()
{
    std::cout << array1 << ' ' << array2 << '\n'
              << s1 << s2 << s3 << std::endl;
    std::wcout << s4 << ' ' << s5 << ' ' << sC
               << std::endl;
}

Вывод:

Foobar Foobar
Hello
  World
Hello
  World
Hello
  World
ABCDEF ABCDEF STUV

Отчеты о дефектах

Следующие отчеты об изменениях в поведении, являющиеся дефектными, были применены ретроактивно к ранее опубликованным стандартам C++.

DR Применяется к Поведение в опубликованной версии Корректное поведение
CWG 411
( P2029R4 )
C++98 escape-последовательности в строковых литералах
не могли отображаться на несколько кодовых единиц
разрешено
CWG 1656
( P2029R4 )
C++98 символы, обозначаемые числовыми escape-
последовательностями в строковых литералах, были неясны
прояснено
CWG 1759 C++11 UTF-8 строковый литерал мог содержать кодовые
единицы, которые не представимы в char
char может представлять все UTF-8 кодовые единицы
CWG 1823 C++98 были ли строковые литералы различными
определялось реализацией
различие не специфицировано, и один и тот же
строковый литерал может давать разные объекты
CWG 2333
( P2029R4 )
C++11 было неясно, разрешены ли числовые escape-последовательности
в UTF-8/16/32 строковых литералах
прояснено
CWG 2870 C++11 результат конкатенации двух
обычных строковых литералов был неясен
прояснено
P1854R4 C++98 обычные и широкие строковые литералы с некодируемыми
символами были условно-поддерживаемыми
программы с такими литералами являются некорректными
P2029R4 C++98 1. было неясно, могут ли строковые литералы
содержать некодируемые символы
2. было неясно, могут ли строковые литералы содержать
числовые escape-последовательности, такие
что кодовые единицы, которые они представляют, не
представимы в типе элемента массива литералов
1. сделано условно-поддерживаемым для
обычных и широких строковых литералов [1]
2. некорректно, если кодовые единицы
не представимы ни в беззнаковом
целочисленном типе, соответствующем
базовому типу
  1. P1854R4 был принят как Defect Report позднее, отменяя данное решение.

Ссылки

  • Стандарт C++23 (ISO/IEC 14882:2024):
  • 5.13.5 Строковые литералы [lex.string]
  • Стандарт C++20 (ISO/IEC 14882:2020):
  • 5.13.5 Строковые литералы [lex.string]
  • Стандарт C++17 (ISO/IEC 14882:2017):
  • 5.13.5 Строковые литералы [lex.string]
  • Стандарт C++14 (ISO/IEC 14882:2014):
  • 2.14.5 Строковые литералы [lex.string]
  • Стандарт C++11 (ISO/IEC 14882:2011):
  • 2.14.5 Строковые литералы [lex.string]
  • Стандарт C++03 (ISO/IEC 14882:2003):
  • 2.13.4 Строковые литералы [lex.string]
  • Стандарт C++98 (ISO/IEC 14882:1998):
  • 2.13.4 Строковые литералы [lex.string]

Смотрите также

пользовательские литералы (C++11) литералы с пользовательским суффиксом
C documentation для Строковые литералы