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

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

Строковые литералы, расположенные рядом, конкатенируются на фазе 6 трансляции (после препроцессора). То есть, "Hello," " world!" даёт (единую) строку "Hello, world!". Если две строки имеют одинаковый префикс кодировки (или ни у одной нет префикса), то результирующая строка будет иметь тот же префикс кодировки (или не будет иметь префикса).

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

L"Δx = %" PRId16 // at phase 4, PRId16 expands to "d"
                 // at phase 6, L"Δx = %" and "d" form L"Δx = %d"

Если строковый литерал UTF-8 и строковый литерал широких символов стоят рядом, программа некорректна.

(с C++11)

Любая другая комбинация префиксов кодировки условно поддерживается с семантикой, определяемой реализацией. (Известно, что ни одна реализация не поддерживает такую конкатенацию.)

(с C++11)
(до C++23)

Любая другая комбинация префиксов кодировки некорректна.

(с C++23)

Неоцениваемые строки

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

  • Спецификация связывания языков
  • static_assert (с C++11)
  • Имя оператора литерала (с C++11)
  • [[deprecated]] (с C++14)
  • [[nodiscard]] (с C++20)

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

(до C++26)

Префикс кодировки не разрешен в этих контекстах.

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

(с C++26)

Примечания

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

Строковые литералы могут быть преобразованы и присвоены неконстантным 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

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

//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++20)
(DR)
Исправление совместимости и переносимости char8_t (разрешить инициализацию массивов (unsigned) char из строковых литералов UTF-8)
__cpp_raw_strings 200710L (C++11) Строковые литералы с сырыми строками
__cpp_unicode_literals 200710L (C++11) Строковые литералы с поддержкой Unicode

Пример

#include <iostream>
 
char array1[] = "Foo" "bar";
// same as
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++.

Отчёт об ошибке Применён к Опубликованное поведение Корректное поведение
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
сделано ясным
P1854R4 C++98 обычные и широкие строковые литералы с некодируемыми
символами условно поддерживались
программы с такими литералами некорректны
P2029R4 C++98 1. Было неясно, могут ли строковые литералы
содержать некодируемые символы
2. Было неясно, могут ли строковые литералы содержать
числовые escape-последовательности, так что кодовые
единицы, которые они представляют, не могут быть
представлены в типе элемента массива литералов
1. условно поддерживались для
обычных и широких строковых литералов[1]
2. Некорректны, если кодовые единицы не могут
быть представлены в типе беззнакового целого числа,
соответствующем базовому типу
  1. P1854R4 был принят как отчёт об ошибке позже, отменяя это решение.

Ссылки

  • Стандарт C++23 (ISO/IEC 14882:2023):
    • 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/w/cpp/language/string_literal

Spec-Zone.ru

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