Spec-Zone.ru › C++

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

Синтаксис

"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
  • управляющая последовательность, определённая в разделе управляющие последовательности
  • универсальное имя символа, определённое в разделе управляющие последовательности
basic-s-char — Символ из набора символов трансляции, за исключением двойной кавычки ", обратной косой черты \ и символа новой строки
d-char-seq — Последовательность из одного или нескольких символов d-char, длиной не более 16 символов
d-char — Символ из базового набора символов, за исключением скобок, обратной косой черты и пробелов
r-char-seq — Последовательность из одного или нескольких символов r-char, которая не должна содержать закрывающую последовательность )d-char-seq"
r-char — Символ из набора символов трансляции
Синтаксис Вид Тип Кодировка
(1,2) обычный строковый литерал constchar[N] кодировка обычных литералов
(3,4) широкий строковый литерал constwchar_t[N] кодировка широких литералов
(5,6) строковый литерал UTF-8

constchar[N]

(до C++20)

constchar8_t[N]

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

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

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

В результате вычисления строкового литерала создаётся объект строкового литерала со статической длительностью хранения. Не специфицировано, хранятся ли все строковые литералы в неперекрывающихся объектах и создают ли последовательные вычисления строкового литерала один и тот же или разные объекты.

Попытка изменить объект строкового литерала приводит к неопределённому поведению.

bool b = "bar" == 3 + "foobar"; // can be true or false, unspecified

const char* pc = "Hello";
char* p = const_cast<char*>(pc);
p[0] = 'M'; // undefined behavior

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

Сырые строковые литералы — это строковые литералы с префиксом, содержащим 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,(начиная с C++11) простых управляющих последовательностей и универсальных имён символов обозначаемая ею последовательность символов кодируется в последовательность кодовых единиц с использованием связанной с этим строковым литералом кодировки символов. Если символ не может быть представлен в связанной кодировке символов, программа некорректна.
Если связанная кодировка символов является кодировкой с состоянием, первая такая последовательность кодируется, начиная с исходного состояния кодировки, а каждая следующая — начиная с конечного состояния кодировки предыдущей последовательности.
2) Для каждой числовой управляющей последовательности, если v — целочисленное значение, представленное восьмеричным или шестнадцатеричным числом, образованным последовательностью цифр в управляющей последовательности, а T — тип элемента массива строкового литерала (см. таблицу выше):
  • Если v не превышает диапазон представимых значений T, управляющая последовательность добавляет одну кодовую единицу со значением v.
  • В противном случае, если строковый литерал имеет синтаксическую форму (1) или (3) и(начиная с C++11) v не превышает диапазон представимых значений соответствующего беззнакового типа для базового типа T, управляющая последовательность добавляет одну кодовую единицу с уникальным значением типа T, сравнимым с v по модулю 2S, где S — ширина T.
  • В противном случае программа некорректна.
Если связанная кодировка символов является кодировкой с состоянием, все такие последовательности не влияют на состояние кодировки.
3) Каждая условная управляющая последовательность добавляет последовательность кодовых единиц, определяемую реализацией.
Если связанная кодировка символов является кодировкой с состоянием, влияние этих последовательностей на состояние кодировки определяется реализацией.

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

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

  • Если оба строковых литерала имеют один и тот же вид, объединённый строковый литерал также имеет этот вид.
  • Если обычный строковый литерал расположен рядом с широким строковым литералом, поведение не определено.
(до C++11)
  • Если обычный строковый литерал расположен рядом с необычным строковым литералом, объединённый строковый литерал имеет вид последнего.
  • Если строковый литерал UTF-8 расположен рядом с широким строковым литералом, программа некорректна.
  • Любое другое сочетание условно поддерживается с семантикой, определяемой реализацией.[1]
(до C++23)
  • Любое другое сочетание некорректно.
(начиная с C++23)
(начиная с C++11)
"Hello, " "world!" // at phase 6, the 2 string literals form "Hello, world!"

L"Δx = %" PRId16   // at phase 4, PRId16 expands to "d"
                   // at phase 6, L"Δx = %" and "d" form L"Δx = %d"
  1. Нет известных реализаций, поддерживающих такую конкатенацию.

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

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

  • спецификация языковой связи
  • static_assert
  • имя литерального оператора
(начиная с C++11)
  • [[deprecated]]
(начиная с C++14)
  • [[nodiscard]]
(начиная с C++20)
  • тело удалённой функции
(начиная с C++26)

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

(до C++26)

В этих контекстах допускаются только обычные строковые литералы.

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

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

Примечания

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

Для совместимости с C строковые литералы можно преобразовывать в указатели char* или wchar_t* и присваивать им, даже если они не являются константными; в C строковые литералы имеют типы char[N] и wchar_t[N]. Такое неявное преобразование устарело.

(до C++11)

Строковые литералы нельзя преобразовывать в указатели CharT*, не являющиеся константными, или присваивать им. Если требуется такое преобразование, необходимо использовать явное приведение (например, const_cast).

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

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

const char* p = "abc\0def"; // std::strlen(p) == 3, but the array has size 8

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

//const char* p = "\xfff"; // error: hexadecimal escape sequence out of range
const char* p = "\xff""f"; // OK: the literal is const char[3] holding {'\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) Строковые литералы Unicode

Пример

#include <iostream>

// array1 and array2 contains the same values:
char array1[] = "Foo" "bar";
char array2[] = {'F', 'o', 'o', 'b', 'a', 'r', '\0'};

const char* s1 = R"foo(
Hello
  World
)foo";
// same as
const char* s2 = "\nHello\n  World\n";
// same as
const char* s3 = "\n"
                 "Hello\n"
                 "  World\n";

const wchar_t* s4 = L"ABC" L"DEF"; // OK, same as
const wchar_t* s5 = L"ABCDEF";
const char32_t* s6 = U"GHI" "JKL"; // OK, same as
const char32_t* s7 = U"GHIJKL";
const char16_t* s9 = "MN" u"OP" "QR"; // OK, same as
const char16_t* sA = u"MNOPQR";

// const auto* sB = u"Mixed" U"Types";
        // before C++23 may or may not be supported by
        // the implementation; ill-formed since C++23

const wchar_t* sC = LR"--(STUV)--"; // OK, raw string literal

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

Ссылки

  • Стандарт 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 о строковых литералах

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

Spec-Zone.ru

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