文字列リテラル
目次 |
[編集] 構文
"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 | - | 1つ以上のs-charのシーケンス |
| s-char | - | 以下のいずれか
|
| basic-s-char | - | 翻訳文字集合の文字で、二重引用符"、バックスラッシュ\、または改行文字を除く |
| d-char-seq | - | 1つ以上のd-charのシーケンスで、最大16文字長 |
| d-char | - | 基本文字集合の文字で、括弧、バックスラッシュ、空白を除く |
| r-char-seq | - | 1つ以上のr-charのシーケンスで、ただし閉じシーケンス)d-char-seq"を含んではならない |
| r-char | - | 翻訳文字集合の文字 |
| 構文 | 種類 | 型 | エンコーディング | ||||
|---|---|---|---|---|---|---|---|
| (1,2) | 通常文字列リテラル | const char[N] | 通常の文字リテラルエンコーディング | ||||
| (3,4) | ワイド文字列リテラル | const wchar_t[N] | ワイド文字リテラルエンコーディング | ||||
| (5,6) | UTF-8文字列リテラル |
|
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
生文字列リテラル生文字列リテラルは、 // 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) で、以下の順序で初期化されます。
T(上記の表参照)とします。- vが
Tの表現可能な値の範囲を超えない場合、エスケープシーケンスは値vを持つ単一のコードユニットを生成します。 - そうでなく、文字列リテラルの構文が(1)または(3)であり、(C++11以降) vが
Tの基になる型の対応する符号なし型の表現可能な値の範囲を超えない場合、エスケープシーケンスは、v mod 2S
に合同であるような、型Tのユニークな値を持つ単一のコードユニットを生成します。ここでSはTの幅です。 - それ以外の場合、プログラムは不適格となります。
[編集] 連結
隣接する文字列リテラルは、翻訳フェーズ6 (プリプロセッシング後) で連結されます。
- 2つの文字列リテラルが同じ種類である場合、連結された文字列リテラルもその種類になります。
|
(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との互換性のために、非 |
(C++11まで) |
|
文字列リテラルは、非 |
(C++11以降) |
文字列リテラルは必ずしもヌル終端の文字シーケンスであるとは限りません。文字列リテラルが埋め込みヌル文字を含む場合、複数の文字列を含む配列を表します。
const char* p = "abc\0def"; // std::strlen(p) == 3, but the array has size 8
文字列リテラル内の16進エスケープシーケンスの後に有効な16進数字が続く場合、無効なエスケープシーケンスとしてコンパイルエラーになります。文字列連結を回避策として使用できます。
//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互換性と移植性の修正(UTF-8文字列リテラルからの(unsigned) char配列の初期化を許可) |
__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 | 2つの通常の文字列リテラルの 連結結果が不明確だった |
明確化された |
| 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 standard (ISO/IEC 14882:2020)
- 5.13.5 文字列リテラル [lex.string]
- C++17 standard (ISO/IEC 14882:2017)
- 5.13.5 文字列リテラル [lex.string]
- C++14 standard (ISO/IEC 14882:2014)
- 2.14.5 文字列リテラル [lex.string]
- C++11 standard (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ドキュメント: 文字列リテラル
| |