Skip to content

Commit e789283

Browse files
committed
C++26 : 「コンパイル時にのみ使用される文字列の扱いを明確化」を追加 (close #1174)
1 parent b8e353b commit e789283

File tree

9 files changed

+86
-2
lines changed

9 files changed

+86
-2
lines changed

implementation-status.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@
297297
| P2752R3: [`std::initializer_list`の配列を静的記憶域に配置する](/lang/cpp26/static_storage_for_braced_initializers.md) | `std::vector v = {1, 2, 3};`のような初期化で初期化子リストを静的記憶域に配置することで無駄なコピーをなくす | 14 | | | |
298298
| P2169R4: [宣言のみで使用しない変数の名前として`_`をサポート](/lang/cpp26/nice_placeholder_with_no_name.md) | 変数名`_`は暗黙で`[[maybe_unused]]`が指定される | 14 | 18 | | |
299299
| P1854R4: [文字列リテラルの文字エンコーディング失敗を不適格とする](/lang/cpp26/making_non-encodable_string_literals_ill-formed.md) | 文字列リテラルのエンコーディング時に文字表現が失われる場合にコンパイルエラーにする | 14 | 14 | | |
300-
| P2361R6: [コンパイル時にのみ使用される文字列の扱いを明確化](/lang/cpp26/unevaluated_strings.md.nolink) | `static_assert``[[deprecated]]`などで使用されるコンパイル時の文字列について、文字コードの指定を禁止し、実行時エンコーディングが行われないことを規定 | 14 | 18 | | |
300+
| P2361R6: [コンパイル時にのみ使用される文字列の扱いを明確化](/lang/cpp26/unevaluated_strings.md) | `static_assert``[[deprecated]]`などで使用されるコンパイル時の文字列について、文字コードの指定を禁止し、実行時エンコーディングが行われないことを規定 | 14 | 18 | | |
301301
| P2552R3: [属性の無視性を見直し](/lang/cpp26/on_the_ignorability_of_standard_attributes.md) | 構文として適格な属性のみを無視できるようにし、そうでない属性の使用を不適格とする | 15 | | | |
302302
| P2738R1: [定数式での`void*`からポインタ型へのキャストを許可](/lang/cpp26/constexpr_cast_from_voidptr.md) | 型消去のために`void*`からポインタ型へのキャストを許可する | 14 | 17 | | |
303303
| P2741R3: [`static_assert`の診断メッセージにユーザーが生成した文字列の指定を許可](/lang/cpp26/user-generated_static_assert_messages.md) | `constexpr``S.size()``S.data()`メンバ関数をもつオブジェクトをコンパイル時文字列として指定できるようにする | 14 | 17 | | |

lang/cpp11/constexpr.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ GCC 5.2、Clang 3.7、Visual C++ 2015時点で、3つともデフォルトは512
220220
- [C++26 `constexpr`配置`new`](/lang/cpp26/constexpr_placement_new.md)
221221
- [C++26 `constexpr`構造化束縛の許可と、`constexpr`参照の制限緩和](/lang/cpp26/constexpr_structured_bindings_and_references_to_constexpr_variables.md)
222222
- [C++26 `constexpr`仮想継承を許可](/lang/cpp26/constexpr_virtual_inheritance.md)
223+
- [C++26 コンパイル時にのみ使用される文字列の扱いを明確化](/lang/cpp26/unevaluated_strings.md)
223224
224225
225226
## 参照

lang/cpp11/static_assert.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ Boost Static Assertion Libraryが開発されたときに、コンパイル時
9393
- [C++17 constexpr if 文](/lang/cpp17/if_constexpr.md)
9494
- [C++23 定数式の文脈での`bool`への縮小変換を許可](/lang/cpp23/narrowing_contextual_conversions_to_bool.md)
9595
- [C++26 `static_assert`の診断メッセージにユーザーが生成した文字列の指定を許可](/lang/cpp26/user-generated_static_assert_messages.md)
96+
- [C++26 コンパイル時にのみ使用される文字列の扱いを明確化](/lang/cpp26/unevaluated_strings.md)
9697
9798
9899
## 参照

lang/cpp14/deprecated_attr.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ prog.cc:45:3: warning: 'class_templ<int>' is deprecated: don't use class_templ<i
132132
## <a id="relative-page" href="#relative-page">関連項目</a>
133133
- [C++11 属性構文](/lang/cpp11/attributes.md)
134134
- [C++23 ラムダ式に対する属性](/lang/cpp23/attributes_on_lambda_expressions.md)
135+
- [C++26 コンパイル時にのみ使用される文字列の扱いを明確化](/lang/cpp26/unevaluated_strings.md)
135136

136137

137138
## 参照

lang/cpp17/nodiscard.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ nodiscard.cpp:11:3: warning: ignoring return value of function declared with 'no
6262
- C++17対応のコンパイラでも使用できる可能性がある
6363
- [C++20 `[[nodiscard]]`属性に理由となる文字列を付加できるようにする](/lang/cpp20/nodiscard_should_have_a_reason.md)
6464
- [C++23 ラムダ式に対する属性](/lang/cpp23/attributes_on_lambda_expressions.md)
65+
- [C++26 コンパイル時にのみ使用される文字列の扱いを明確化](/lang/cpp26/unevaluated_strings.md)
6566

6667

6768
## 参照

lang/cpp26.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ C++26とは、2026年中に改訂される予定の、C++バージョンの通
2525
| 言語機能 | 説明 |
2626
|----------|------|
2727
| [文字列リテラルの文字エンコーディング失敗を不適格とする](/lang/cpp26/making_non-encodable_string_literals_ill-formed.md) | 文字列リテラルのエンコーディング時に文字表現が失われる場合にコンパイルエラーにする |
28-
| [コンパイル時にのみ使用される文字列の扱いを明確化](/lang/cpp26/unevaluated_strings.md.nolink) | `static_assert``[[deprecated]]`などで使用されるコンパイル時の文字列について、文字コードの指定を禁止し、実行時エンコーディングが行われないことを規定 |
28+
| [コンパイル時にのみ使用される文字列の扱いを明確化](/lang/cpp26/unevaluated_strings.md) | `static_assert``[[deprecated]]`などで使用されるコンパイル時の文字列について、文字コードの指定を禁止し、実行時エンコーディングが行われないことを規定 |
2929

3030

3131
### 分岐・ループ

lang/cpp26/making_non-encodable_string_literals_ill-formed.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ char c = 'é'; // C++23:実装定義, C++26:NG グレイブアクセントをつ
2929

3030
## 関連項目
3131
- [C++23 1ワイド文字に収まらないワイド文字リテラルを禁止する](/lang/cpp23/remove_non_encodable_wide_character_literals_and_multicharacter_wide_character_literals.md)
32+
- [C++26 コンパイル時にのみ使用される文字列の扱いを明確化](/lang/cpp26/unevaluated_strings.md)
3233

3334

3435
## 参照

lang/cpp26/unevaluated_strings.md

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# コンパイル時にのみ使用される文字列の扱いを明確化 [P2361R6]
2+
* cpp26[meta cpp]
3+
4+
<!-- start lang caution -->
5+
6+
このページはC++26に採用される見込みの言語機能の変更を解説しています。
7+
8+
のちのC++規格でさらに変更される場合があるため[関連項目](#relative-page)を参照してください。
9+
10+
<!-- last lang caution -->
11+
12+
## 概要
13+
文字列リテラルは、文字配列の初期化だけでなく、コンパイル時の診断メッセージやプリプロセッシング、その他の実装定義の動作にも使用される。これらのコンパイル時にのみ使用される文字列は「非評価文字列 (unevaluated string)」と呼ばれ、実行時のエンコーディングに変換されることはない。
14+
15+
C++26では、非評価文字列が使用される文脈を明確にし、これらの文字列に対して以下の制約を設ける:
16+
17+
- エンコーディングプレフィックス (`L`, `u`, `U`, `u8`) は許可されない
18+
- 文字列は実行時エンコーディングに変換されない
19+
- ユニバーサルキャラクタ名および (単純な) エスケープシーケンス (`\0`を除く) はUnicodeコードポイントに置換され、数値エスケープシーケンスなどその他のエスケープシーケンスは不適格となる
20+
21+
これらの変更は既存コードとの互換性を崩す変更 (破壊的変更) ではあるが、オープンソースプロジェクトの調査では、既存コードへの影響はほぼないとされている。
22+
23+
24+
## 非評価文字列が使用される文脈
25+
26+
| 文脈 | 説明 |
27+
|-----------|------|
28+
| [`static_assert`](/lang/cpp11/static_assert.md) | 表明失敗時の診断メッセージ |
29+
| [`[[deprecated]]`](/lang/cpp14/deprecated_attr.md) | 非推奨の理由メッセージ |
30+
| [`[[nodiscard]]`](/lang/cpp17/nodiscard.md) | 戻り値無視時の警告メッセージ |
31+
| [`= delete`](/lang/cpp26/delete_reason.md) | 削除された関数の診断メッセージ |
32+
| `extern` | リンケージ指定の文字列 (例: `extern "C"`) |
33+
| `_Pragma` | プリプロセッサプラグマの文字列 |
34+
| `asm` | インラインアセンブリの文字列 |
35+
| `#line` | 行番号ディレクティブのファイル名 |
36+
| リテラル演算子 | ユーザー定義リテラルの接尾辞識別 |
37+
38+
39+
## 仕様
40+
### エンコーディングプレフィックスの禁止
41+
非評価文字列には、エンコーディングプレフィックスを指定できない。
42+
43+
```cpp
44+
// C++23まで: 実装定義の動作
45+
// C++26: 不適格
46+
static_assert(true, L"message");
47+
static_assert(true, u8"message");
48+
49+
// C++26: OK
50+
static_assert(true, "message");
51+
```
52+
53+
### エスケープシーケンスの制限
54+
非評価文字列では、ユニバーサルキャラクタ名 (`\uNNNN`, `\UNNNNNNNN`) と (単純な) エスケープシーケンス (`\\`, `\"`, `\n`など。ただし`\0`を除く) のみが許可される。数値エスケープシーケンス (`\x1B`, `\012`など) は不適格となる。
55+
56+
```cpp
57+
// C++26: OK
58+
static_assert(true, "hello\nworld"); // エスケープシーケンス
59+
static_assert(true, "\u0041"); // ユニバーサルキャラクタ名
60+
61+
// C++26: 不適格 (数値エスケープシーケンス)
62+
static_assert(true, "\x48\x65\x6c\x6c\x6f");
63+
```
64+
65+
これは、コンパイラが非評価文字列を実行時エンコーディングに変換しないため、数値エスケープシーケンスによるコードユニットの直接指定が意味を持たないためである。
66+
67+
68+
## <a id="relative-page" href="#relative-page">関連項目</a>
69+
- [C++11 `constexpr`](/lang/cpp11/constexpr.md)
70+
- [C++11 コンパイル時アサート](/lang/cpp11/static_assert.md)
71+
- [C++14 `[[deprecated]]`属性](/lang/cpp14/deprecated_attr.md)
72+
- [C++17 `[[nodiscard]]`属性](/lang/cpp17/nodiscard.md)
73+
- [C++26 文字列リテラルの文字エンコーディング失敗を不適格とする](/lang/cpp26/making_non-encodable_string_literals_ill-formed.md)
74+
- [C++26 `static_assert`の診断メッセージにユーザーが生成した文字列の指定を許可](/lang/cpp26/user-generated_static_assert_messages.md)
75+
76+
77+
## 参照
78+
- [P2361R6 Unevaluated Strings](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2361r6.pdf)

lang/cpp26/user-generated_static_assert_messages.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ static_assert(定数式, 診断メッセージ);
5454
## <a id="relative-page" href="#relative-page">関連項目</a>
5555
- [C++11 コンパイル時アサート](/lang/cpp11/static_assert.md)
5656
- [C++17 `static_assert`のメッセージ省略を許可](/lang/cpp17/extending_static_assert.md)
57+
- [C++26 コンパイル時にのみ使用される文字列の扱いを明確化](/lang/cpp26/unevaluated_strings.md)
5758

5859

5960
## 参照

0 commit comments

Comments
 (0)