How is Boxed value moved


I’m still wondering about how a stored value in a Box is moved. In the following piece of code

struct S {
    s: Box<String>,

impl S {
    fn new() -> Self {
        let s = Box::new(String::from("hello"));
        println!("s: {:p}", s);   // addr: address of s on the heap
        Self { s }

fn main() {
    let s0 = S::new();
    println!("s0: {:p}", s0.s);  // addr0: should be equal to addr?
    let s1 = s0;
    println!("s1: {:p}", s1.s);  // addr1: should be equal to addr0, or not?

Running the example, I always got the same address for addr, addr0 and addr1.

I suppose that addr == addr0, but still not sure whether it is guaranteed that addr0 == addr1?

Many thanks for any response.


Moving a Box doesn’t move what the Box points to. fmt::Pointer formatting prints the address of what is stored in the Box.


Also even for types that do change address when moved, the optimizer is free to optimize the move out.


But moreover, we can be certain that no such types exist. A move is a memcpy that cannot possibly change the output of fmt::Pointer::fmt. (well, okay, I guess you could do something silly like have impl Pointer format &self which is of type &&Self, but that’s not what I mean…)

I’m pretty sure this is guaranteed, as long as it is observable. As in, as long as you do something like print addresses or compare raw pointers (*const T) through equality, LLVM will suppress optimizations that would invalidate this. (that said, I think it’s already extremely conservative with optimizations around heap allocations)

However, beware; the inverse proposition is not true. As in, two pointers are allowed to be equal even if they point to different things in Rust, due to the existence of zero-sized types.

1 Like

I’ve meant this:

fn main() {
    struct Foo(u8);
    let foo = Foo(1);
    println!("{:p}", &foo);
    let bar = foo;
    println!("{:p}", &bar);

It seems that printing the address forces the compiler to have a unique one, but moves that aren’t observed are optimized out:

1 Like