1- # 未初期化変数の読み取りを誤り起因動作とする [ P2795R5]
1+ # 未初期化変数の読み取りを「erroneous behavior」とする [ P2795R5]
22* cpp26[ meta cpp]
33
44<!-- start lang caution -->
1010<!-- last lang caution -->
1111
1212## 概要
13- C++23までは、未初期化変数 (デフォルト初期化された変数) の読み取りは未定義動作として扱われていた。C++26では、この未定義動作による安全上のリスクを低減するため、「誤り起因動作 (erroneous behavior; 通称 EB)」を新設してその多くに割り当てることとした。
13+ C++23までは、未初期化変数 (デフォルト初期化された変数) の読み取りは未定義動作として扱われていた。C++26では、この未定義動作による安全上のリスクを低減するため、「「erroneous behavior」 (erroneous behavior; 通称 EB)」を新設してその多くに割り当てることとした。
1414
1515``` cpp example
1616// C++23
@@ -24,7 +24,7 @@ int main() {
2424
2525未初期化の値は、コンパイラやターゲット環境によって定義された固定値である。コンパイラにはこの誤りを診断することが許可され、推奨されているが、誤りを無視して有効な読み取りとして扱うことも許可されている。このコードは誤りではあるが、未定義動作に関連する結果に遭遇するリスクはない。
2626
27- 誤り起因動作は未定義動作とはちがって 、明確に定義された動作をするがコードとして正しくない、ということを規定するものであり、処理系に対して有用な診断を提供するものである。
27+ 「erroneous behavior」は未定義動作とはちがって 、明確に定義された動作をするがコードとして正しくない、ということを規定するものであり、処理系に対して有用な診断を提供するものである。
2828
2929C++26では、不定値で初期化されることを明確に指示する`[[indeterminate]]`属性も導入され、以下のような動作となる:
3030
@@ -33,56 +33,56 @@ C++26では、不定値で初期化されることを明確に指示する`[[ind
3333void f(int) {}
3434
3535int main() {
36- int x; // xは誤り起因動作を引き起こす未初期化値をもつ
36+ int x; // xは「erroneous value」をもつ
3737 int y [[indeterminate]]; // 意図して不定値に初期化されることを指示
3838
39- f(x); // 誤り起因動作 (未初期化値の読み取り)
39+ f(x); // erroneous behavior (未初期化値の読み取り)
4040 f(y); // 未定義動作 (不定値の読み取り)
4141}
4242```
4343
4444
4545## 仕様
4646- 式が評価された結果として不定値が生成された場合、未定義動作を引き起こす
47- - 式が評価された結果として未初期化値が生成された場合、誤り起因動作を引き起こす
48- - 未初期価値が生成されることで誤り起因動作を引き起こす対象は以下 :
47+ - 式が評価された結果として未初期化値が生成された場合、「erroneous behavior」を引き起こす
48+ - 未初期価値が生成されることで「erroneous behavior」を引き起こす対象は以下 :
4949 - 自動記憶域期間をもつオブジェクトのうち、` void ` 以外のスカラ型
5050 - 注意 : 動的記憶域期間をもつオブジェクトは対象外
51- - ただし、` unsigned char ` もしくは[ ` std::byte ` ] ( /reference/cstddef/byte.md ) 型に関しては、未初期化値をもつ変数を同じ型の変数に代入するだけでは誤り起因動作にならず、値の参照や型変換がされることで誤り起因動作を引き起こす
52- - 誤り起因動作が引き起こされた結果値は、後続の処理では誤り起因動作を引き起こす値とはみなされない
51+ - ただし、` unsigned char ` もしくは[ ` std::byte ` ] ( /reference/cstddef/byte.md ) 型に関しては、未初期化値をもつ変数を同じ型の変数に代入するだけでは「erroneous behavior」にならず、値の参照や型変換がされることで「erroneous behavior」を引き起こす
52+ - 「erroneous behavior」が引き起こされた結果値は、後続の処理では「erroneous value」とはみなされない
5353
5454``` cpp example
5555#include < cassert>
5656
5757int g (bool b) {
5858 unsigned char c;
59- unsigned char d = c; // 誤り起因動作ではない。dは誤り起因動作を引き起こす未初期化値をもつ
59+ unsigned char d = c; // 「erroneous behavior」ではない。dは「erroneous value」をもつ
6060
61- assert(c == d); // 常に真、誤り起因動作 (整数昇格)
61+ assert(c == d); // 常に真、「erroneous behavior」 (整数昇格)
6262
63- int e = d; // 誤り起因動作 (型変換)
64- return b ? d : 0; // bがtrueの場合に誤り起因動作
63+ int e = d; // 「erroneous behavior」 (型変換)
64+ return b ? d : 0; // bがtrueの場合に「erroneous behavior」
6565}
6666
6767int main() {
6868 int d1, d2;
6969
70- int e1 = d1; // 誤り起因動作
71- int e2 = d1; // 誤り起因動作
70+ int e1 = d1; // 「erroneous behavior」
71+ int e2 = d1; // 「erroneous behavior」
7272
7373 // 処理が続行した場合…
74- assert(e1 == e2); // 常に真、誤り起因動作ではない 。
75- // 誤り起因動作の結果で生成された値 (e1とe2) は、
76- // 誤り起因動作を引き起こす値とはみなされない
77- assert(e1 == d1); // 常に真、誤り起因動作
78- assert(e2 == d1); // 常に真、誤り起因動作
79-
80- // 誤り起因動作ではないが
81- // d2は誤り起因動作を引き起こす未初期化値をもつ
74+ assert(e1 == e2); // 常に真、「erroneous behavior」ではない 。
75+ // 「erroneous behavior」の結果で生成された値 (e1とe2) は、
76+ // 「erroneous value」とはみなされない
77+ assert(e1 == d1); // 常に真、「erroneous behavior」
78+ assert(e2 == d1); // 常に真、「erroneous behavior」
79+
80+ // 「erroneous behavior」ではないが
81+ // d2は「erroneous value」をもつ
8282 std::memcpy(&d2, &d1, sizeof(int));
8383
84- assert(e1 == d2); // 誤り起因動作
85- assert(e2 == d2); // 誤り起因動作
84+ assert(e1 == d2); // 「erroneous behavior」
85+ assert(e2 == d2); // 「erroneous behavior」
8686}
8787```
8888
@@ -109,9 +109,9 @@ int main() {
109109}
110110```
111111
112- ### 今後、誤り起因動作に分類される可能性のある操作
112+ ### 今後、「erroneous behavior」に分類される可能性のある操作
113113
114- 現在、未定義動作に分類される以下の操作は、誤り起因動作に分類できる可能性がある 。
114+ 現在、未定義動作に分類される以下の操作は、「erroneous behavior」に分類できる可能性がある 。
115115
116116| 操作 | 備考 |
117117| ------| ------|
@@ -120,8 +120,8 @@ int main() {
120120| 誤ったビットシフト (負のシフト幅や、上限を超えたシフト幅) | 符号付き整数のオーバーフローと同じ |
121121| ゼロ割り | いくつかの固定値での誤った結果となる可能性がある。影響が不明確であるため、変更にはコストがかかる |
122122| 戻り値型が非` void ` な関数から返った、もしくは` [[noreturn]] ` 属性をつけた関数から返った | [ ` std::terminate() ` ] ( /reference/exception/terminate.md ) が呼ばれる可能性がある。変更には軽いコストがかかるが、その変更にどの程度の価値があるかは不明 |
123- | 抽象クラスのコンストラクタ・デストラクタからの純粋仮想関数の呼び出し | 特定の純粋仮想ハンドラが呼ばれる可能性がある。実装によってはすでに誤り起因動作のように扱われている可能性がある |
124- | 契約違反 | 契約に関する現在の策定作業では、契約違反時になにが起こるべきかという問題に直面している。誤り起因動作という概念は有用な回答を与えてくれる可能性がある |
123+ | 抽象クラスのコンストラクタ・デストラクタからの純粋仮想関数の呼び出し | 特定の純粋仮想ハンドラが呼ばれる可能性がある。実装によってはすでに「erroneous behavior」のように扱われている可能性がある |
124+ | 契約違反 | 契約に関する現在の策定作業では、契約違反時になにが起こるべきかという問題に直面している。「erroneous behavior」という概念は有用な回答を与えてくれる可能性がある |
125125
126126
127127
0 commit comments