hiro99ma blog

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 のアドレスが同じになって *r20 になった。
環境によりけりなのでビルドの仕方とかで変わってくるだろう。
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 は見たことがある、くらいでしかないな。。。


 < Top page


コメント(Google Formへ飛びます)

GitHub

X/Twitter

Homepage