1
+ <!--
1
2
# Checked Uninitialized Memory
3
+ -->
2
4
5
+ # チェックされる初期化されていないメモリ
6
+
7
+ <!--
3
8
Like C, all stack variables in Rust are uninitialized until a value is
4
9
explicitly assigned to them. Unlike C, Rust statically prevents you from ever
5
10
reading them until you do:
11
+ -->
12
+
13
+ C のように、 Rust の全てのスタック上の変数は、値が明示的に代入されるまでは初期化されません。 C とは違い、 Rust では、
14
+ 値が代入されるまで、初期化されていない変数を読み込もうとするのを静的に防ぎます。
6
15
7
16
``` rust,ignore
8
17
fn main() {
@@ -13,15 +22,23 @@ fn main() {
13
22
14
23
``` text
15
24
src/main.rs:3:20: 3:21 error: use of possibly uninitialized variable: `x`
25
+ (エラー: 初期化されていないかもしれない変数 `x` を使用しています)
16
26
src/main.rs:3 println!("{}", x);
17
27
^
18
28
```
19
29
30
+ <!--
20
31
This is based off of a basic branch analysis: every branch must assign a value
21
32
to `x` before it is first used. Interestingly, Rust doesn't require the variable
22
33
to be mutable to perform a delayed initialization if every branch assigns
23
34
exactly once. However the analysis does not take advantage of constant analysis
24
35
or anything like that. So this compiles:
36
+ -->
37
+
38
+ これは、基本的な分岐分析に基づいています。すなわち、全ての分岐は、 ` x ` が初めに
39
+ 使用される前に、値を代入しなければなりません。興味深いことに、 Rust では、もし全ての分岐の中で
40
+ 値がちょうど一回しか代入されない場合、遅延初期化を行なうために変数をミュータブルにする必要がありません。
41
+ しかし、この分析は定数の分析や、それに似たものを利用していないため、このコードはコンパイルできます。
25
42
26
43
``` rust
27
44
fn main () {
@@ -37,7 +54,11 @@ fn main() {
37
54
}
38
55
```
39
56
57
+ <!--
40
58
but this doesn't:
59
+ -->
60
+
61
+ しかし、このコードはコンパイルできません。
41
62
42
63
``` rust,ignore
43
64
fn main() {
@@ -51,10 +72,15 @@ fn main() {
51
72
52
73
``` text
53
74
src/main.rs:6:17: 6:18 error: use of possibly uninitialized variable: `x`
75
+ (エラー: 初期化されていないかもしれない変数 `x` を使用しています)
54
76
src/main.rs:6 println!("{}", x);
55
77
```
56
78
79
+ <!--
57
80
while this does:
81
+ -->
82
+
83
+ 一方でこのコードはコンパイルできます。
58
84
59
85
``` rust
60
86
fn main () {
@@ -63,55 +89,75 @@ fn main() {
63
89
x = 1 ;
64
90
println! (" {}" , x );
65
91
}
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
+ // 値をその分岐で使用しないからです。
68
94
}
69
95
```
70
96
97
+ <!--
71
98
Of course, while the analysis doesn't consider actual values, it does
72
99
have a relatively sophisticated understanding of dependencies and control
73
100
flow. For instance, this works:
101
+ -->
102
+
103
+ もちろん、分析では実際の値は考慮されませんが、比較的洗練された、依存関係や制御フローに関する
104
+ 分析は行われます。例えば、このコードは動作します。
74
105
75
106
``` rust
76
107
let x : i32 ;
77
108
78
109
loop {
79
- // Rust doesn't understand that this branch will be taken unconditionally,
80
- // because it relies on actual values.
110
+ // Rust は、この分岐が状況によらず選択されることは理解しません。
111
+ // なぜならこれは、実際の値に依存するためです。
81
112
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` はミュータブルとしてマークされる必要がないのです。
85
116
x = 0 ;
86
117
break ;
87
118
}
88
119
}
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` はこの場所において初期化されなければならないと知っているのです !
91
122
println! (" {}" , x );
92
123
```
93
124
125
+ <!--
94
126
If a value is moved out of a variable, that variable becomes logically
95
127
uninitialized if the type of the value isn't Copy. That is:
128
+ -->
129
+
130
+ もし値の型が Copy を実装しておらず、値が変数からムーブされたら、
131
+ 論理的にはその変数は初期化されていない事になります。
96
132
97
133
``` rust
98
134
fn main () {
99
135
let x = 0 ;
100
136
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 は論理的には初期化されていません
103
139
}
104
140
```
105
141
142
+ <!--
106
143
However reassigning `y` in this example *would* require `y` to be marked as
107
144
mutable, as a Safe Rust program could observe that the value of `y` changed:
145
+ -->
146
+
147
+ しかしながらこの例では、 ` y ` に値を再代入しようとするのであれば、 ` y ` を
148
+ ミュータブルとしてマークする必要が* あるでしょう* 。
149
+ 安全な Rust のプログラムは ` y ` の値が変わったと認識出来るからです。
108
150
109
151
``` rust
110
152
fn main () {
111
153
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 を再初期化します
114
156
}
115
157
```
116
158
159
+ <!--
117
160
Otherwise it's like `y` is a brand new variable.
161
+ -->
162
+
163
+ そうでなければ、 ` y ` は全く新しい変数のようなものです。
0 commit comments