Skip to content

Instantly share code, notes, and snippets.

@toku-sa-n
Last active May 28, 2021 08:58
Show Gist options
  • Save toku-sa-n/1b822f8005bc4bbd44b4b1704825ccae to your computer and use it in GitHub Desktop.
Save toku-sa-n/1b822f8005bc4bbd44b4b1704825ccae to your computer and use it in GitHub Desktop.
生ポインタのメモ

Rustの生ポインタ

参照規則

あるオブジェクトに対する,存在しうる参照は以下の通り.

  • 複数の不変参照
  • 唯一の可変参照

同じオブジェクトに対する不変参照と可変参照が同時に存在したり,複数の可変参照が同時に存在したりすることはあってはならない.

生ポインタの参照外し

一時的に可変参照を生成するため,参照規則に違反する可能性がある.次のコードは未定義動作を引き起こす(コード).

fn main() {
    let mut value = 3;
    let mut_ref = &mut value;
    let mut_ptr = mut_ref as *mut i32;

    *mut_ref = 4;

    unsafe {
        *mut_ptr = 5; // UB
    }

    assert_eq!(value, 5);
}

Miriの出力:

   Compiling playground v0.0.1 (/playground)
    Finished dev [unoptimized + debuginfo] target(s) in 0.53s
     Running `/playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/cargo-miri target/x86_64-unknown-linux-gnu/debug/playground`
error: Undefined Behavior: no item granting write access to tag <untagged> at alloc1390 found in borrow stack.
 --> src/main.rs:9:9
  |
9 |         *mut_ptr = 5;
  |         ^^^^^^^^^^^^ no item granting write access to tag <untagged> at alloc1390 found in borrow stack.
  |
  = help: this indicates a potential bug in the program: it performed an invalid operation, but the rules it violated are still experimental
  = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
          
  = note: inside `main` at src/main.rs:9:9
  = note: inside `<fn() as std::ops::FnOnce<()>>::call_once - shim(fn())` at /playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:227:5
  = note: inside `std::sys_common::backtrace::__rust_begin_short_backtrace::<fn(), ()>` at /playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sys_common/backtrace.rs:125:18
  = note: inside closure at /playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/rt.rs:49:18
  = note: inside `std::ops::function::impls::<impl std::ops::FnOnce<()> for &dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe>::call_once` at /playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:259:13
  = note: inside `std::panicking::r#try::do_call::<&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe, i32>` at /playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:401:40
  = note: inside `std::panicking::r#try::<i32, &dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe>` at /playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:365:19
  = note: inside `std::panic::catch_unwind::<&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe, i32>` at /playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:433:14
  = note: inside `std::rt::lang_start_internal` at /playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/rt.rs:34:21
  = note: inside `std::rt::lang_start::<()>` at /playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/rt.rs:48:5

error: aborting due to previous error

参考文献

Do aliasing mutable raw pointers (*mut T) cause undefined behaviour?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment