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