1+ <!--
12# Checked Uninitialized Memory
3+ -->
24
5+ # チェックされる初期化されていないメモリ
6+
7+ <!--
38Like C, all stack variables in Rust are uninitialized until a value is
49explicitly assigned to them. Unlike C, Rust statically prevents you from ever
510reading them until you do:
11+ -->
12+
13+ C のように、 Rust の全てのスタック上の変数は、値が明示的に代入されるまでは初期化されません。 C とは違い、 Rust では、
14+ 値が代入されるまで、初期化されていない変数を読み込もうとするのを静的に防ぎます。
615
716``` rust,ignore
817fn main() {
@@ -13,15 +22,23 @@ fn main() {
1322
1423``` text
1524src/main.rs:3:20: 3:21 error: use of possibly uninitialized variable: `x`
25+ (エラー: 初期化されていないかもしれない変数 `x` を使用しています)
1626src/main.rs:3 println!("{}", x);
1727 ^
1828```
1929
30+ <!--
2031This is based off of a basic branch analysis: every branch must assign a value
2132to `x` before it is first used. Interestingly, Rust doesn't require the variable
2233to be mutable to perform a delayed initialization if every branch assigns
2334exactly once. However the analysis does not take advantage of constant analysis
2435or anything like that. So this compiles:
36+ -->
37+
38+ これは、基本的な分岐分析に基づいています。すなわち、全ての分岐は、 ` x ` が初めに
39+ 使用される前に、値を代入しなければなりません。興味深いことに、 Rust では、もし全ての分岐の中で
40+ 値がちょうど一回しか代入されない場合、遅延初期化を行なうために変数をミュータブルにする必要がありません。
41+ しかし、この分析は定数の分析や、それに似たものを利用していないため、このコードはコンパイルできます。
2542
2643``` rust
2744fn main () {
@@ -37,7 +54,11 @@ fn main() {
3754}
3855```
3956
57+ <!--
4058but this doesn't:
59+ -->
60+
61+ しかし、このコードはコンパイルできません。
4162
4263``` rust,ignore
4364fn main() {
@@ -51,10 +72,15 @@ fn main() {
5172
5273``` text
5374src/main.rs:6:17: 6:18 error: use of possibly uninitialized variable: `x`
75+ (エラー: 初期化されていないかもしれない変数 `x` を使用しています)
5476src/main.rs:6 println!("{}", x);
5577```
5678
79+ <!--
5780while this does:
81+ -->
82+
83+ 一方でこのコードはコンパイルできます。
5884
5985``` rust
6086fn main () {
@@ -63,55 +89,75 @@ fn main() {
6389 x = 1 ;
6490 println! (" {}" , x );
6591 }
66- // Don't care that there are branches where it's not initialized
67- // since we don't use the value in those branches
92+ // 初期化されない分岐があっても構いません。
93+ // 値をその分岐で使用しないからです。
6894}
6995```
7096
97+ <!--
7198Of course, while the analysis doesn't consider actual values, it does
7299have a relatively sophisticated understanding of dependencies and control
73100flow. For instance, this works:
101+ -->
102+
103+ もちろん、分析では実際の値は考慮されませんが、比較的洗練された、依存関係や制御フローに関する
104+ 分析は行われます。例えば、このコードは動作します。
74105
75106``` rust
76107let x : i32 ;
77108
78109loop {
79- // Rust doesn't understand that this branch will be taken unconditionally,
80- // because it relies on actual values.
110+ // Rust は、この分岐が状況によらず選択されることは理解しません。
111+ // なぜならこれは、実際の値に依存するためです。
81112 if true {
82- // But it does understand that it will only be taken once because
83- // we unconditionally break out of it. Therefore `x` doesn't
84- // need to be marked as mutable.
113+ // しかし Rust は、この分岐がたった一回しか選択されないと理解しています。
114+ // なぜなら、状況によらず、この分岐を抜け出すからです。
115+ // それゆえ、`x` はミュータブルとしてマークされる必要がないのです。
85116 x = 0 ;
86117 break ;
87118 }
88119}
89- // It also knows that it's impossible to get here without reaching the break.
90- // And therefore that `x` must be initialized here !
120+ // Rust はまた、 break に到達せずに、ここに来ることが不可能だということを知っています。
121+ // そしてそれゆえに、 `x` はこの場所において初期化されなければならないと知っているのです !
91122println! (" {}" , x );
92123```
93124
125+ <!--
94126If a value is moved out of a variable, that variable becomes logically
95127uninitialized if the type of the value isn't Copy. That is:
128+ -->
129+
130+ もし値の型が Copy を実装しておらず、値が変数からムーブされたら、
131+ 論理的にはその変数は初期化されていない事になります。
96132
97133``` rust
98134fn main () {
99135 let x = 0 ;
100136 let y = Box :: new (0 );
101- let z1 = x ; // x is still valid because i32 is Copy
102- let z2 = y ; // y is now logically uninitialized because Box isn't Copy
137+ let z1 = x ; // i32 は Copy を実装しているため、 x はまだ有効です
138+ let z2 = y ; // Box は Copy を実装していないため、もはや y は論理的には初期化されていません
103139}
104140```
105141
142+ <!--
106143However reassigning `y` in this example *would* require `y` to be marked as
107144mutable, as a Safe Rust program could observe that the value of `y` changed:
145+ -->
146+
147+ しかしながらこの例では、 ` y ` に値を再代入しようとするのであれば、 ` y ` を
148+ ミュータブルとしてマークする必要が* あるでしょう* 。
149+ 安全な Rust のプログラムは ` y ` の値が変わったと認識出来るからです。
108150
109151``` rust
110152fn main () {
111153 let mut y = Box :: new (0 );
112- let z = y ; // y is now logically uninitialized because Box isn't Copy
113- y = Box :: new (1 ); // reinitialize y
154+ let z = y ; // Box が Copy を実装していないため、もはや y は論理的には初期化されていません
155+ y = Box :: new (1 ); // y を再初期化します
114156}
115157```
116158
159+ <!--
117160Otherwise it's like `y` is a brand new variable.
161+ -->
162+
163+ そうでなければ、 ` y ` は全く新しい変数のようなものです。
0 commit comments