Skip to content

Commit 93e79ef

Browse files
committed
C++26 : 「要素数不明の配列を集成体初期化する規則を明確化」を追加 (close #1323)
1 parent fd7bea7 commit 93e79ef

File tree

3 files changed

+100
-2
lines changed

3 files changed

+100
-2
lines changed

implementation-status.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@
302302
| P2662R3: [パラメータパックへのインデックスアクセスを許可](/lang/cpp26/pack_indexing.md) | 可変引数テンプレートのパラメータパックに添字アクセスできるようにする | 15 | | | |
303303
| P2864R2: [非推奨となっていた列挙値から算術型への暗黙変換を削除](/lang/cpp26/remove_deprecated_arithmetic_conversion_on_enumerations.md) | C++20から非推奨となっていた列挙値への算術演算で算術型に暗黙変換される仕様を削除 | 14 | 18 | | |
304304
| P2748R5: [返却された左辺値から暗黙変換された一時オブジェクトが参照に束縛されることを禁止する](/lang/cpp26/disallow_binding_a_returned_glvalue_to_a_temporary.md) | 寿命切れの変数によって引き起こされるバグを防止する | 14 | 19 | | |
305-
| P3106R1: [要素数不明の配列を集成体初期化する規則を明確化](/lang/cpp26/clarifying_rules_for_brace_elision_in_aggregate_initialization.md.nolink) | 配列要素の集成体初期化で`{}`が省略された場合の矛盾していた規定を修正 | yes | 17 | | |
305+
| P3106R1: [要素数不明の配列を集成体初期化する規則を明確化](/lang/cpp26/clarifying_rules_for_brace_elision_in_aggregate_initialization.md) | 配列要素の集成体初期化で`{}`が省略された場合の矛盾していた規定を修正 | yes | 17 | | |
306306
| P0609R3: [構造化束縛への属性を許可](/lang/cpp26/attributes_for_structured_bindings.md) | `auto [a, b [[maybe_unused]], c] = f();`のように構造化束縛の要素に対して属性を付加できるようにする | 15 | 19 | | |
307307
| P3034R1: [モジュール宣言でのモジュール名のマクロ展開を禁止する](/lang/cpp26/module_declarations_shouldnt_be_macros.md) | `export module MACRO_NAME;`を禁止 | 15 | | | |
308308
| P2809R3: [空の無限ループは未定義動作ではないと規定](/lang/cpp26/trivial_infinite_loops_are_not_undefined_behavior.md) | 並行プログラムの進行保証などを考慮して空の無限ループを未定義動作ではないものとする | 14 | 19 | | |

lang/cpp26.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ C++26とは、2026年中に改訂される予定の、C++バージョンの通
1515
| [宣言のみで使用しない変数の名前として`_`をサポート](/lang/cpp26/nice_placeholder_with_no_name.md) | 変数名`_`は暗黙で`[[maybe_unused]]`が指定される |
1616
| [不完全型へのポインタに対する`delete`を不適格とする](/lang/cpp26/deleting_a_pointer_to_an_incomplete_type_should_be_ill-formed.md) | 未定義動作を引き起こす操作をコンパイルエラーとする |
1717
| [返却された左辺値から暗黙変換された一時オブジェクトが参照に束縛されることを禁止する](/lang/cpp26/disallow_binding_a_returned_glvalue_to_a_temporary.md) | 寿命切れの変数によって引き起こされるバグを防止する |
18-
| [要素数不明の配列を集成体初期化する規則を明確化](/lang/cpp26/clarifying_rules_for_brace_elision_in_aggregate_initialization.md.nolink) | 配列要素の集成体初期化で`{}`が省略された場合の矛盾していた規定を修正 |
18+
| [要素数不明の配列を集成体初期化する規則を明確化](/lang/cpp26/clarifying_rules_for_brace_elision_in_aggregate_initialization.md) | 配列要素の集成体初期化で`{}`が省略された場合の矛盾していた規定を修正 |
1919
| [未初期化変数の読み取りをエラー性動作とする](/lang/cpp26/erroneous_behavior_for_uninitialized_reads.md) | 初期化されていない自動変数の読み取りの安全性を規定する |
2020
| [構造化束縛でパックを導入できるようにする](/lang/cpp26/structured_bindings_can_introduce_a_pack.md) | タプルを分解する際に複数の変数をパックとして宣言できるようにする。`auto [a, ...xs] = f();` |
2121

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# 要素数不明の配列を集成体初期化する規則を明確化 [P3106R1]
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+
C++26では、集成体の配列を初期化する際に、中括弧 `{}` を省略した場合の動作について、規格内で矛盾があった問題を修正する。
14+
15+
C++23までの仕様として、要素数不明の配列を初期化する際、配列の要素数は初期化子リスト内の初期化子の数で決まると規定されていた。しかしこの仕様では、中括弧 `{}` を省略した場合の動作に矛盾があった:
16+
17+
```cpp
18+
struct X { int i, j, k = 42; };
19+
20+
// 実際の動作としては、どちらの要素数も2になる。
21+
// C++23仕様ではaは6になるはずだが、実態と合っていない
22+
X a[] = { 1, 2, 3, 4, 5, 6 };
23+
X b[2] = { { 1, 2, 3 }, { 4, 5, 6 } };
24+
```
25+
26+
C++26ではこれを、実際のコンパイラの動作に合わせた仕様に修正する。動作としてはおそらく変わることはないと考えられる。
27+
28+
そのほかの例:
29+
30+
```cpp
31+
struct S1 { int a, b; };
32+
struct S2 { S1 s, t; };
33+
34+
// xとyは同じ値
35+
S2 x[2] = { 1, 2, 3, 4, 5, 6, 7, 8 };
36+
S2 y[2] = {
37+
{
38+
{ 1, 2 },
39+
{ 3, 4 }
40+
},
41+
{
42+
{ 5, 6 },
43+
{ 7, 8 }
44+
}
45+
};
46+
```
47+
48+
```cpp
49+
// y[3]要素の初期化子は省略されている
50+
float y[4][3] = {
51+
{ 1, 3, 5 },
52+
{ 2, 4, 6 },
53+
{ 3, 5, 7 },
54+
};
55+
56+
// この初期化子は上記と同じ効果を持つ
57+
float y[4][3] = {
58+
1, 3, 5, 2, 4, 6, 3, 5, 7
59+
};
60+
```
61+
62+
```cpp
63+
struct S { } s;
64+
struct A {
65+
S s1;
66+
int i1;
67+
S s2;
68+
int i2;
69+
S s3;
70+
int i3;
71+
} a = {
72+
{ }, // s1の初期化子
73+
0,
74+
s, // s2の初期化子
75+
0
76+
}; // s3とi3は未初期化
77+
```
78+
79+
```cpp
80+
struct A {
81+
int i;
82+
operator int();
83+
};
84+
struct B {
85+
A a1, a2;
86+
int z;
87+
};
88+
89+
A a;
90+
B b = { 4, a, a };
91+
// b.a1.iは4で初期化
92+
// b.a2はaで初期化
93+
// b.zはaのint変換演算子の結果で初期化
94+
```
95+
96+
97+
## 参照
98+
- [P3106R1 Clarifying rules for brace elision in aggregate initialization](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3106r1.html)

0 commit comments

Comments
 (0)