-
Notifications
You must be signed in to change notification settings - Fork 168
C++26 : 「未初期化変数の読み取りをエラー性動作とする」を追加 #1349
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 1 commit
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
90c7ce3
C++26 : 「未初期化変数の読み取りを誤り起因動作とする」を追加
faithandbrave cd6d39b
C++26 未初期化変数の読み取り : erroneous behavior後の結果値に関する説明を整理
faithandbrave 040c509
C++26 未初期化変数の読み取り : コード例にexampleをつけた
faithandbrave a114975
用語定義 : erroneous behaviorの概要を実態に合うよう修正
faithandbrave 7f7759e
C++26 未初期化変数の読み取り : 概要を整理
faithandbrave 6b0e3d7
C++26 未初期化変数の読み取り : assert結果を明記
faithandbrave 2a4fe0e
C++26 未初期化変数の読み取り : 動的確保されたオブジェクトが対象外であることを記載
faithandbrave 30cfb4e
erroneous behavior/valueを一旦訳さない
faithandbrave 7d2188d
C++26 未初期化値の読み取り : 未定義動作になりえるケースを記載
faithandbrave c965e26
用語 : 読みを修正
faithandbrave 7e68271
C++26 未初期化変数の読み取り : 訳してない用語のマーキング
faithandbrave aeee953
C++26 未初期化変数の読み取り : 仕様説明を見直し
faithandbrave 5e8c37d
C++26 未初期化変数の読み取り : indeterminateのサンプルコードミスを修正
faithandbrave afee388
C++26 未初期化変数の読み取り : 抜けていた「常に真」を追加
faithandbrave 94e04bf
C++26 未初期化変数の読み取り : boolの例示を見直し
faithandbrave a81c832
C++26 未初期化変数の読み取り : 「明確に定義された動作」を削除
faithandbrave 616c00b
C++26 未初期化変数の読み取り : 今後の話を仕様から備考に移動
faithandbrave 82d6360
C++26 未初期化変数の読み取り : 決定した訳語を適用
faithandbrave 6010481
GLOBAL_DEFINED_WORDS: EB に倣い UB も英名を表記
akinomyoga 28eb999
標準規格と処理系: エラー性の動作を言及
akinomyoga 1c11eb8
fix typo
faithandbrave File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
121 changes: 121 additions & 0 deletions
121
lang/cpp26/erroneous_behavior_for_uninitialized_reads.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
# 未初期化変数の読み取りを誤り起因動作とする [P2795R5] | ||
* cpp26[meta cpp] | ||
|
||
<!-- start lang caution --> | ||
|
||
このページはC++26に採用される見込みの言語機能の変更を解説しています。 | ||
|
||
のちのC++規格でさらに変更される場合があるため[関連項目](#relative-page)を参照してください。 | ||
|
||
<!-- last lang caution --> | ||
|
||
## 概要 | ||
これまで、未初期化変数 (デフォルト初期化された変数) の読み取りは未定義動作として扱われていた。C++26では、この操作が安全上のリスクをもたらさないものとして、「誤り起因動作 (erroneous behavior; 通称 EB)」を新設してそれに割り当てることとした。 | ||
faithandbrave marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
この変更の対象は、デフォルト初期化されたスカラ型 (`void`以外の組み込み型) 変数の読み取りであり、以下のようなケースである。 | ||
k-satoda marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
```cpp | ||
// C++23 | ||
void f(int); | ||
|
||
int main() { | ||
int x; // デフォルト初期化。xは不定値 (indeterminate value) をもつ | ||
f(x); // 左辺値から右辺値への変換が未定義動作を引き起こす | ||
} | ||
``` | ||
|
||
未初期化の値は、コンパイラやターゲット環境によって定義された固定値である。コンパイラにはこの誤りを診断することが許可され、推奨されているが、誤りを無視して有効な読み取りとして扱うことも許可されている。このコードは誤りではあるが、未定義動作に関連する結果に遭遇するリスクはない。 | ||
k-satoda marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
誤り起因動作は未定義動作とはちがって、明確に定義された動作をするがコードとして正しくない、ということを規定するものであり、処理系に対して有用な診断を提供するものである。 | ||
|
||
C++26では、不定値で初期化されることを明確に指示する`[[indeterminate]]`属性も導入され、以下のような動作となる: | ||
|
||
```cpp | ||
// C++26 | ||
void f(int); | ||
|
||
int main() { | ||
int x; // xは誤り起因動作を引き起こす未初期化値をもつ | ||
int y [[indeterminate]]; // 意図して不定値に初期化されることを指示 | ||
|
||
f(x); // 誤り起因動作 (未初期化値の読み取り) | ||
f(y); // 未定義動作 (不定値の読み取り) | ||
} | ||
``` | ||
|
||
|
||
## 仕様 | ||
- 式が評価された結果として不定値が生成された場合、未定義動作を引き起こす | ||
- 式が評価された結果として未初期化値が生成された場合、誤り起因動作を引き起こす | ||
- ただし、`unsigned char`もしくは[`std::byte`](/reference/cstddef/byte.md)型に関しては、未初期化値をもつ変数を同じ型の変数に代入するだけでは誤り起因動作にならず、値の参照や型変換がされることで誤り起因動作を引き起こす | ||
- 誤り起因動作が引き起こされた結果値は、後続の処理では誤り起因動作を引き起こす値とはみなされない | ||
faithandbrave marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
```cpp | ||
faithandbrave marked this conversation as resolved.
Show resolved
Hide resolved
|
||
int g(bool b) { | ||
unsigned char c; | ||
unsigned char d = c; // 誤り起因動作ではない。dは誤り起因動作を引き起こす未初期化値をもつ | ||
|
||
assert(c == d); // どちらの変数も整数昇格され誤り起因動作となる | ||
|
||
int e = d; // 誤り起因動作 (型変換) | ||
return b ? d : 0; // bがtrueの場合に誤り起因動作 | ||
} | ||
|
||
void h() { | ||
int d1, d2; | ||
|
||
int e1 = d1; // 誤り起因動作 | ||
int e2 = d1; // 誤り起因動作 | ||
|
||
// 処理が続行した場合… | ||
assert(e1 == e2); // OK。誤り起因動作の結果で生成された値は正常 | ||
assert(e1 == d1); // 誤り起因動作 | ||
assert(e2 == d1); // 誤り起因動作 | ||
|
||
// 誤り起因動作ではないが | ||
// d2は誤り起因動作を引き起こす未初期化値をもつ | ||
std::memcpy(&d2, &d1, sizeof(int)); | ||
|
||
assert(e1 == d2); // 誤り起因動作 | ||
assert(e2 == d2); // 誤り起因動作 | ||
} | ||
``` | ||
|
||
### `[[indeterminate]]`属性 | ||
`[[indeterminate]]`属性は、自動変数が初期状態として意図して不定値をもつことを指示するものであり、自動変数の定義、もしくは関数のパラメータ宣言に適用できる。 | ||
|
||
関数のパラメータが`[[indeterminate]]`属性で宣言される場合、その関数の最初の宣言でそのように宣言されなければならない (注:関数宣言は複数行うことができるが、その最初の宣言で`[[indeterminate]]`属性をつけなければならない)。 | ||
|
||
`[[indeterminate]]`がつけられた変数から読み取りをした場合、未定義動作を引き起こす可能性がある。 | ||
|
||
```cpp | ||
struct T { | ||
T() {} | ||
int x; | ||
}; | ||
|
||
int h(T t [[indeterminate]]) { | ||
f(t.x); // この関数呼び出しは未定義動作を引き起こす | ||
faithandbrave marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return 0; | ||
} | ||
int _ = h(T()); | ||
``` | ||
|
||
### 今後、誤り起因動作に分類される可能性のある操作 | ||
|
||
現在、未定義動作に分類される以下の操作は、誤り起因動作に分類できる可能性がある。 | ||
|
||
| 操作 | 備考 | | ||
|------|------| | ||
| 符号付き整数のオーバーフロー | 演算結果としてオーバーフローした場合に誤った結果になる可能性がある。これは珍しいバグではない。これは安全上の大きな問題ではない | | ||
| 算術型の変換結果としてその型の表現可能な範囲を超えた | 符号付き整数のオーバーフローと同じ | | ||
| 誤ったビットシフト (負のシフト幅や、上限を超えたシフト幅) | 符号付き整数のオーバーフローと同じ | | ||
| ゼロ割り | いくつかの固定値での誤った結果となる可能性がある。影響が不明確であるため、変更にはコストがかかる | | ||
| 戻り値型が非`void`な関数から返った、もしくは`[[noreturn]]`属性をつけた関数から返った | [`std::terminate()`](/reference/exception/terminate.md)が呼ばれる可能性がある。変更には軽いコストがかかるが、その変更にどの程度の価値があるかは不明 | | ||
| 抽象クラスのコンストラクタ・デストラクタからの純粋仮想関数の呼び出し | 特定の純粋仮想ハンドラが呼ばれる可能性がある。実装によってはすでに誤り起因動作のように扱われている可能性がある | | ||
| 契約違反 | 契約に関する現在の策定作業では、契約違反時になにが起こるべきかという問題に直面している。誤り起因動作という概念は有用な回答を与えてくれる可能性がある | | ||
|
||
|
||
|
||
## 参照 | ||
- [P2795R5 Erroneous behaviour for uninitialized reads](https://open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2795r5.html) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.