Zeichenkettenliteral
Inhalt |
[bearbeiten] Syntax
"s-char-seq (optional)" |
(1) | ||||||||
R"d-char-seq (optional)(r-char-seq (optional))d-char-seq (optional)" |
(2) | (seit C++11) | |||||||
L"s-char-seq (optional)" |
(3) | ||||||||
LR"d-char-seq (optional)(r-char-seq (optional))d-char-seq (optional)" |
(4) | (seit C++11) | |||||||
u8"s-char-seq (optional)" |
(5) | (seit C++11) | |||||||
u8R"d-char-seq (optional)(r-char-seq (optional))d-char-seq (optional)" |
(6) | (seit C++11) | |||||||
u"s-char-seq (optional)" |
(7) | (seit C++11) | |||||||
uR"d-char-seq (optional)(r-char-seq (optional))d-char-seq (optional)" |
(8) | (seit C++11) | |||||||
U"s-char-seq (optional)" |
(9) | (seit C++11) | |||||||
UR"d-char-seq (optional)(r-char-seq (optional))d-char-seq (optional)" |
(10) | (seit C++11) | |||||||
[bearbeiten] Erklärung
| s-char-seq | - | Eine Folge von einem oder mehreren s-char s |
| s-char | - | Einer von
|
| basic-s-char | - | Ein Zeichen aus dem Übersetzungszeichensatz, außer dem doppelten Anführungszeichen ", dem umgekehrten Schrägstrich \ oder dem Zeilenumbruchzeichen |
| d-char-seq | - | Eine Folge von einem oder mehreren d-char s, höchstens 16 Zeichen lang |
| d-char | - | Ein Zeichen aus dem Grundzeichensatz, außer Klammern, umgekehrtem Schrägstrich und Leerzeichen |
| r-char-seq | - | Eine Folge von einem oder mehreren r-char s, mit der Ausnahme, dass sie nicht die schließende Sequenz )d-char-seq" enthalten darf |
| r-char | - | Ein Zeichen aus dem Übersetzungszeichensatz |
| Syntax | Art | Typ | Kodierung | ||||
|---|---|---|---|---|---|---|---|
| (1,2) | gewöhnliches Zeichenkettenliteral | const char[N] | gewöhnliche Literal-Kodierung | ||||
| (3,4) | breites Zeichenkettenliteral | const wchar_t[N] | breite Literal-Kodierung | ||||
| (5,6) | UTF-8-Zeichenkettenliteral |
|
UTF-8 | ||||
| (7,8) | UTF-16-Zeichenkettenliteral | const char16_t[N] | UTF-16 | ||||
| (9,10) | UTF-32-Zeichenkettenliteral | const char32_t[N] | UTF-32 |
In den obigen Typen ist N die Anzahl der kodierten Code Units, die weiter unten bestimmt wird.
Gewöhnliche und UTF-8(seit C++11)-Zeichenkettenliterale werden gemeinsam als schmale Zeichenkettenliterale bezeichnet.
Die Auswertung eines Zeichenkettenliterals ergibt ein Zeichenkettenliteral-Objekt mit statischer Speicherdauer. Ob alle Zeichenkettenliterale in nicht überlappenden Objekten gespeichert werden und ob aufeinanderfolgende Auswertungen eines Zeichenkettenliterals dasselbe oder ein anderes Objekt ergeben, ist nicht spezifiziert.
Der Versuch, ein Zeichenkettenliteral-Objekt zu modifizieren, führt zu undefiniertem Verhalten.
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
Raw-ZeichenkettenliteraleRaw-Zeichenkettenliterale sind Zeichenkettenliterale mit einem Präfix, der // 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 |
(seit C++11) |
[bearbeiten] Initialisierung
Zeichenkettenliteral-Objekte werden mit der Code-Unit-Sequenz initialisiert, die den Code-Unit-Werten der s-char -Sequenz und r-char s(seit C++11) des Zeichenkettenliterals entspricht, zuzüglich eines abschließenden Nullzeichens (U+0000), in der folgenden Reihenfolge:
T der Elementtyp des Arrays des Zeichenkettenliterals ist (siehe Tabelle oben)- Wenn v den Bereich der darstellbaren Werte von
Tnicht überschreitet, trägt die Escape-Sequenz eine einzelne Code Unit mit dem Wert v. - Andernfalls, wenn das Zeichenkettenliteral die Syntax (1) oder (3) hat, und(seit C++11) v den Bereich der darstellbaren Werte des entsprechenden vorzeichenlosen Typs für den zugrundeliegenden Typ von
Tnicht überschreitet, dann trägt die Escape-Sequenz eine einzelne Code Unit mit einem eindeutigen Wert vom TypT, der kongruent zu v mod 2S
ist, wobei S die Breite vonTist. - Andernfalls ist das Programm fehlerhaft.
[bearbeiten] Konkatenation
Nebeneinanderliegende Zeichenkettenliterale werden in Übersetzungsphase 6 (nach der Präprozessierung) konkateniert.
- Wenn die beiden Zeichenkettenliterale vom selben Typ sind, ist das konkatenierte Zeichenkettenliteral ebenfalls von diesem Typ.
|
(bis C++11) | ||||
|
(seit 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"
- ↑ Keine bekannte Implementierung unterstützt eine solche Konkatenation.
[bearbeiten] Nicht ausgewertete Zeichenketten
Die folgenden Kontexte erwarten ein Zeichenkettenliteral, werten es aber nicht aus:
- Spezifikation der Sprachverknüpfung
|
(seit C++11) |
|
(seit C++14) |
|
(seit C++20) |
| (seit C++26) |
|
Es ist nicht spezifiziert, ob nicht-gewöhnliche Zeichenkettenliterale in diesen Kontexten erlaubt sind, mit der Ausnahme, dass ein Literaloperatorname ein gewöhnliches Zeichenkettenliteral verwenden muss(seit C++11). |
(bis C++26) |
|
Nur gewöhnliche Zeichenkettenliterale sind in diesen Kontexten erlaubt. Jeder universelle Zeichenname und jede einfache Escape-Sequenz in einer nicht ausgewerteten Zeichenkette wird durch das Mitglied des Übersetzungszeichensatzes ersetzt, das sie bezeichnet. Eine nicht ausgewertete Zeichenkette, die eine numerische Escape-Sequenz oder eine bedingte Escape-Sequenz enthält, ist ill-formed. |
(seit C++26) |
[bearbeiten] Anmerkungen
Zeichenkettenliterale können zur Initialisierung von Zeichenarrays verwendet werden. Wenn ein Array wie char str[] = "foo"; initialisiert wird, enthält str eine Kopie der Zeichenkette "foo".
|
Zeichenkettenliterale sind in nicht-const char* oder wchar_t* konvertierbar und zuweisbar, um mit C kompatibel zu sein, wo Zeichenkettenliterale die Typen char[N] und wchar_t[N] haben. Eine solche implizite Konvertierung ist veraltet. |
(bis C++11) |
|
Zeichenkettenliterale sind nicht in nicht-const |
(seit C++11) |
Ein Zeichenkettenliteral ist nicht notwendigerweise eine nullterminierte Zeichenfolge: Wenn ein Zeichenkettenliteral eingebettete Nullzeichen enthält, repräsentiert es ein Array, das mehr als eine Zeichenkette enthält.
const char* p = "abc\0def"; // std::strlen(p) == 3, but the array has size 8
Wenn eine gültige hexadezimale Ziffer einer hexadezimalen Escape-Sequenz in einem Zeichenkettenliteral folgt, schlägt die Kompilierung aufgrund einer ungültigen Escape-Sequenz fehl. Zeichenkettenkonkatenation kann als Workaround dienen.
//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'}
| Feature-Test-Makro | Wert | Std | Feature |
|---|---|---|---|
__cpp_char8_t |
202207L |
(C++23) (DR20) |
Kompatibilität und Portabilität von char8_t (ermöglicht Initialisierung von (vorzeichenlosen) char-Arrays aus UTF-8-Zeichenkettenliteralen) |
__cpp_raw_strings |
200710L |
(C++11) | Raw-Zeichenkettenliterale |
__cpp_unicode_literals |
200710L |
(C++11) | Unicode-String-Literale |
[bearbeiten] Beispiel
#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; }
Ausgabe
Foobar Foobar Hello World Hello World Hello World ABCDEF ABCDEF STUV
[bearbeiten] Fehlerberichte
Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | angewendet auf | Verhalten wie veröffentlicht | Korrigiertes Verhalten |
|---|---|---|---|
| CWG 411 (P2029R4) |
C++98 | Escape-Sequenzen in Zeichenkettenliteralen konnten nicht auf mehrere Code Units abgebildet werden |
erlaubt |
| CWG 1656 (P2029R4) |
C++98 | die durch numerische Escape-Sequenzen bezeichneten Zeichen in Zeichenkettenliteralen waren unklar |
wurde klargestellt |
| CWG 1759 | C++11 | ein UTF-8-Zeichenkettenliteral konnte Code Units enthalten, die in char nicht darstellbar sind |
char kann alle UTF-8-Code-Units darstellen |
| CWG 1823 | C++98 | ob Zeichenkettenliterale unterschiedlich waren war implementierungsdefiniert |
Unterschiedlichkeit ist nicht spezifiziert, und dasselbe Zeichenkettenliteral kann unterschiedliche Objekte ergeben |
| CWG 2333 (P2029R4) |
C++11 | es war unklar, ob numerische Escape-Sequenzen in UTF-8/16/32-Zeichenkettenliteralen erlaubt waren |
wurde klargestellt |
| CWG 2870 | C++11 | Das Konkatenationsergebnis zweier gewöhnlicher Zeichenkettenliterale war unklar |
wurde klargestellt |
| P1854R4 | C++98 | gewöhnliche und breite Zeichenkettenliterale mit nicht kodierbaren Zeichen waren bedingt unterstützt |
Programme mit solchen Literalen sind ill-formed |
| P2029R4 | C++98 | 1. Es war unklar, ob Zeichenkettenliterale nicht kodierbare Zeichen enthalten konnten 2. Es war unklar, ob Zeichenkettenliterale numerische Escape-Sequenzen enthalten konnten, so dass die von ihnen dargestellten Code Units nicht im Array-Element-Typ des Literals darstellbar sind |
1. bedingt unterstützt für gewöhnliche und breite Zeichenkettenliterale[1] 2. ill-formed, wenn die Code Units weder im vorzeichenlosen Ganzzahltyp darstellbar sind, der dem zugrundeliegenden Typ entspricht oder dem zugrundeliegenden Typ. |
- ↑ P1854R4 wurde später als DR akzeptiert und überschrieb diese Auflösung.
[bearbeiten] Referenzen
- C++23 Standard (ISO/IEC 14882:2024)
- 5.13.5 Zeichenkettenliterale [lex.string]
- C++20 Standard (ISO/IEC 14882:2020)
- 5.13.5 Zeichenkettenliterale [lex.string]
- C++17 Standard (ISO/IEC 14882:2017)
- 5.13.5 Zeichenkettenliterale [lex.string]
- C++14 Standard (ISO/IEC 14882:2014)
- 2.14.5 Zeichenkettenliterale [lex.string]
- C++11 Standard (ISO/IEC 14882:2011)
- 2.14.5 Zeichenkettenliterale [lex.string]
- C++03-Standard (ISO/IEC 14882:2003)
- 2.13.4 Zeichenkettenliterale [lex.string]
- C++98 Standard (ISO/IEC 14882:1998)
- 2.13.4 Zeichenkettenliterale [lex.string]
[bearbeiten] Siehe auch
| benutzerdefinierte Literale(C++11) | Literale mit benutzerdefiniertem Suffix |
| C-Dokumentation für Zeichenkettenliterale
| |