rust: Rustがんばろう 17日目
2025/04/16
はじめに
生活時間。
10.3章
サンプルコードのこれは、r
を参照するタイミングではなく代入するタイミングでエラーになった。
スコープの外側にある変数に代入するので、これはわかる。
fn bad() {
let r;
{
let x = 5;
r = &x; // ここがエラーになる
}
println!("r: {}", r);
}
では、スコープの中で r
を参照し、抜ける前にスコープ外の変数の参照を代入したらどうなるか?
これもエラーになるのだが、&x
の方は許され、&s
の方がエラーになる。
cannot mutate immutable variable 'r'
なので、&x
を代入したあとで代入したからというだけで let mut r
にすればエラーではなくなる。
fn bad() {
let r;
let s = 12;
{
let x = 5;
r = &x;
println!("r: {}", r);
r = &s; // rがmutではないのでここがエラーになる
}
println!("r: {}", r);
}
C言語だとこんな感じか。
gcc で -Wall
しても警告は出ない。
まあ、このくらいだとスタックに上書きする人がいないので 5
が維持されるが。
#include <stdio.h>
int main(void)
{
int *r;
{
int x = 5;
r = &x;
}
printf("r: %d\n", *r);
return 0;
}
たとえばこんな風にすると x
のアドレスと y
のアドレスが同じになって *r
は 20
になった。
環境によりけりなのでビルドの仕方とかで変わってくるだろう。
printf
で &y
を出力しているところを y
を出力するようにすると、
たぶん最適化されて y
はスタックではなくレジスタで処理されるためか *r
は破壊されない。
#include <stdio.h>
int main(void)
{
int *r;
{
int x = 5;
printf("&x=%p\n", &x);
r = &x;
}
int y = 20;
printf("&y=%p\n", &y);
printf("r: %d\n", *r);
return 0;
}
借用チェッカーに出てくる 'a
とか 'b
は見たことがある、くらいでしかないな。。。